2012-02-29 25 views
0

이 코드는 소켓 수신기 프로그램에서 가져온 것입니다. 문제는 내가 전체 메시지를 듣지 못하고 있다는 것이다. 나는 1382 바이트를 받고있다. 그러나 코드에서 볼 수 있듯이 배열 크기를 15000으로 정의했습니다.수신 소켓 메시지 잘림

namespace Listener 
{ 
    class Server 
    { 
     static void Main(string[] args) 
     { 
      IPAddress localAddr = IPAddress.Parse(args[0]); 
      System.Console.WriteLine("The local IP is {0}", 
localAddr); 
      Int32 port = int.Parse(args[1]); 
      System.Console.WriteLine("The port is {0}", port); 
      TcpListener myListener = new TcpListener(localAddr, 
port); 
      byte[] bytes = new byte[15000]; 
      string sem = ""; 
      do 
      { 
       Console.Write("Waiting"); 
       myListener.Start(); 
       Socket mySocket = myListener.AcceptSocket(); 
       // receiving the hl7 message    
       mySocket.Receive(bytes); 
       string receiveMessage = 
Encoding.ASCII.GetString(bytes); 
       // write out the hl7 message to a receiving 
folder 
       DateTime currentDate = DateTime.Now; 
       long eTicks = currentDate.Ticks; 
       System.IO.File.WriteAllText(@"y:\results\" + 
eTicks + ".hl7", receiveMessage); 
       // build the acknowledgemnent message to send 
back to the client 
       try 
       { 

도움 주셔서 감사합니다.

답변

1

Socket.Receive()는 각 호출에서 첫 번째 데이터 그램 만 가져옵니다. 첫 번째 호출에서 클라이언트 측에서 보낸 1382 바이트 이상인지 확인하십시오.

보낼 데이터가 더있는 경우 클라이언트가 하나의 Send 통화를 대기하거나 Receive()를 계속 호출하고 완료 될 때까지 다른 버퍼에 추가합니다.

예 : 찾고있는 것은 논 블로킹 IO입니다. 이를 구현하는 한 가지 방법은 here입니다.

internal class Server 
{ 
    private static void Main(string[] args) 
    { 
     IPAddress localAddr = IPAddress.Parse(args[0]); 
     System.Console.WriteLine("The local IP is {0}", 
           localAddr); 
     Int32 port = int.Parse(args[1]); 
     System.Console.WriteLine("The port is {0}", port); 
     TcpListener myListener = new TcpListener(localAddr, 
               port); 
     byte[] bytes = new byte[15000]; 
     string sem = ""; 
     do 
     { 
      Console.Write("Waiting"); 
      myListener.Start(); 
      Socket mySocket = myListener.AcceptSocket(); 
      var clientConn = new ClientConnection(mySocket); 
     } while (true); 
    } 
} 

public class ClientConnection 
{ 
    private const int BUFFER_SIZE = 15000; 
    readonly private byte[] _buffer = new byte[BUFFER_SIZE]; 
    readonly private Socket _socket; 
    readonly private StringBuilder _output = new StringBuilder(); 

    public ClientConnection(Socket socket) 
    { 
     _socket = socket; 
     _socket.BeginReceive(_buffer, 0, BUFFER_SIZE, SocketFlags.None, ReadCallback, null); 
    } 

    private void ReadCallback(IAsyncResult ar) 
    { 
     var read = _socket.EndReceive(ar); 

     if (read > 0) 
     { 
      // receiving the hl7 message    
      string receiveMessage = Encoding.ASCII.GetString(_buffer, 0, read); 
      _output.Append(receiveMessage); 

      _socket.BeginReceive(_buffer, 0, BUFFER_SIZE, SocketFlags.None, ReadCallback, null); 
     } 
     else 
     { 

      // write out the hl7 message to a receiving folder 
      DateTime currentDate = DateTime.Now; 
      long eTicks = currentDate.Ticks; 
      System.IO.File.WriteAllText(@"y:\results\" + eTicks + ".hl7", _output.ToString()); 

      SendAcknowledgement(); 
     } 
    } 

    private void SendAcknowledgement() 
    { 
     // build the acknowledgemnent message to send back to the client 
    } 
} 

내가이를 확인하지 못했지만, 그것은 올바른 방향으로 당신을 얻을해야합니다 당신은 클라이언트 연결 당 클래스가있는 경우, 그것은 다음과 같을 수 있습니다. 나는 클라이언트가 데이터 전송을 마쳤을 때 서버가 그것을 읽는 것을 멈춰야한다고 생각했다. 또한 귀하의 do {}가 새로운 연결을 기다리는 무한 루프의 시작이라고 가정했습니다. BeginAccept()를 사용하여 코드의 해당 부분을 비 블로킹으로 만들 수도 있지만, 필요한 경우 사용 사례에 따라 다릅니다.

이 방법으로 열 때마다 새로운 ThreadPool 스레드가 생성됩니다.

+0

완벽하게 작동하는 것처럼 들리는 제이. Receive() 명령을 영원히 차단하지 않고이 작업을 수행 할 수있는 코드 예제를 제공 할 수 있습니까? –

+0

제이, 저는 당신의 아이디어를 제 코드의 기초로 사용했고 오늘 아침에 클라이언트와 함께 테스트 할 것입니다. 필요한 경우 답변 및 업데이트로 표시하겠습니다. 도움에 다시 한번 감사드립니다. –