2013-02-03 4 views
0

이전에 비슷한 질문을했지만 그 방법을 찾지 못했습니다. 일부 데이터가 손실 될 수 있고 마지막 메시지의 일부로 일부 데이터가 올 수 있으므로 TCP를 통해 데이터를 전송할 때 문제가 있음을 이해합니다. 목록에서 일련의 명령을 보내는 중 수정하려고합니다.TCP를 통해 여러 메시지 보내기

여기에 보내는 내 클라이언트의 코드입니다 :

private void sendBtn_Click(object sender, EventArgs e) 
     { 
      try 
      { 
       for (int i = 0; i < listORequestedCommands.Items.Count; i++) 
       { 
        clientSock.Send(Encoding.Default.GetBytes(listORequestedCommands.Items[i].ToString()), listORequestedCommands.Items[i].ToString().Length, SocketFlags.None); 
       } 
       removeAll_Click(sender, e); 
       sendBtn.Enabled = false; 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message, "Error!"); 
       this.Close(); 
      } 

     } 

여기 수신 내 서버 코드입니다 : 내가 크기 접두사 및 직렬화 뭔가를 지시했다

private void clientReceived(Client sender, byte[] data) 
     { 
      try 
      { 
       Invoke((MethodInvoker)delegate 
       { 
        for (int i = 0; i < lstClients.Items.Count; i++) 
        { 
         Client client = lstClients.Items[i].Tag as Client; 

         if (client.ID == sender.ID) 
         { 
          string incommingCommand = Encoding.Default.GetString(data); 
          if (incommingCommand.CompareTo("") != 0) 
          { 
           lstClients.Items[i].SubItems[1].Text = incommingCommand; 
           string[] splittedIncommingCommand = incommingCommand.Split(' '); 

           int numRunProc = 0; 

           do 
           { 
            numRunProc = countProcesses(); 
           } 
           while ((numRunProc >= maxProcesses) || (numRunProc + Int32.Parse(splittedIncommingCommand[splittedIncommingCommand.Length - 1]) >= maxProcesses)); 

           Process processToRun = new Process(); 
           processToRun.StartInfo.FileName = splittedIncommingCommand[0]; 
           processToRun.StartInfo.WorkingDirectory = Path.GetDirectoryName(splittedIncommingCommand[0]); 
           processToRun.StartInfo.Arguments = ""; 

           for (int j = 1; j < splittedIncommingCommand.Length; j++) 
           { 
            processToRun.StartInfo.Arguments += " " + splittedIncommingCommand[j]; 
           } 

           processToRun.Start(); 
          } 
          break; 
         } 
        } 
       }); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message, "Error!"); 
       this.Close(); 
      } 

     } 

, 하지만 문제가 생겨서 제대로 작동하지 않는 것 같습니다.

+0

기본 구조를 이해하고 있거나 문제에 대한 해결책을 찾고 싶습니까? – MarcF

+0

TCP에 대한 이해가 잘못되었습니다. TCP는 패킷이 순서대로 전달되고 패킷 손실없이 전달되도록합니다. 자세한 내용은 http://en.wikipedia.org/wiki/Transmission_Control_Protocol을 참조하십시오. –

+0

사실 나는 둘 다에 관심이 있습니다. 지금은 솔루션이 필요합니다. 버전을 릴리스해야하기 때문입니다. 그러나 앞으로의 사용을 위해이 정보를 이해하고 싶습니다. 감사. – Idanis

답변

0

크기 접두사와 직렬화가 정확히 무엇을 의미하는지 모르겠지만 클라이언트가 얼마나 많은 바이트를 가져야하는지 또는 서버에 메시지의 끝을 "표시"해야한다는 것을 서버에 알리는 것이 좋습니다 즉, 두 개의 CRLF 또는 유사 태그/설명 (예 :)의 eom > 또는 <!과 같은 끝의 문자열. 첫 번째 옵션의 경우 일반적으로 이진 데이터를 사용해야합니다. 두 번째 샘플 코드를 쉽게 보인다.

+0

그래, 그게 내가 들었던 해결책 같아. 그 방법을 보여 주시겠습니까, 왜냐하면 내가 clientSock.Send ... 행에 게시 한 코드에서 시도한 것이기 때문입니다. 당신이 설명 할 수 있다면, 그것은 좋을 것입니다. 감사! – Idanis

+0

목록에서 문자열을 작성하고 끝 기호 (예 : listORequestedCommands.Items [i] .ToString() + "")를 추가하고 클라이언트에서 전송하십시오. EndsWith ""까지 클라이언트에서 문자열을 읽도록 서버 측 코드를 수정하십시오. 그게 다야. –

0

요청한대로 network library networkcomms.net을 사용하여 해결책을 드릴 수 있습니다. 아래의 코드 예제는 단일 문자열을 전송합니다. 당신이 보내는 것을 쉽게 그것을

NetworkComms.AppendGlobalIncomingPacketHandler<string[]> 

또는

에 서버 섹션

NetworkComms.AppendGlobalIncomingPacketHandler<string> 

를 변경하여 string[], List<string> 등을 사용하여 수정할 수 있습니다

NetworkComms.AppendGlobalIncomingPacketHandler<List<string>> 

클라이언트 측 관계없이 그대로 유지 . 다음과 같이 서버의 코드는 다음과 같습니다

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using NetworkCommsDotNet; 

namespace TCPServer 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      NetworkComms.AppendGlobalIncomingPacketHandler<string>("Message", (packetHeader, connection, incomingString) => 
      { 
        Console.WriteLine("The server received a string - " + incomingString); 
        //Perform any other operations on the string you want to here. 
      }); 

      TCPConnection.StartListening(true); 

      Console.WriteLine("Server ready. Press any key to shutdown server."); 
      Console.ReadKey(true); 
      NetworkComms.Shutdown(); 
     } 
    } 
} 

을 그리고 클라이언트 : 당신이 그것을 추가 할 수 있도록

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using NetworkCommsDotNet; 

namespace TCPClient 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string messageToSend = "This is the message to send"; 
      TCPConnection.GetConnection(new ConnectionInfo("127.0.0.1", 10000)).SendObject("Message", messageToSend); 

      Console.WriteLine("Press any key to exit client."); 
      Console.ReadKey(true); 
      NetworkComms.Shutdown(); 
     } 
    } 
} 

당신은 분명히 웹 사이트에서 NetworkCommsDotNet DLL을 다운로드해야합니다 ' NetworkCommsDotNet을 사용하여 '참조. 클라이언트의 서버 IP 주소도 현재 "127.0.0.1"입니다. 동일한 컴퓨터에서 서버와 클라이언트를 모두 실행하는 경우이 옵션이 작동합니다. 자세한 내용은 getting started 또는 how to create a client server application 기사를 확인하십시오.

관련 문제