2012-02-29 15 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バイト以上があることを確認します。

送信するデータがさらにある場合は、クライアントが1つのSend呼び出しをキューに入れるか、Receive()を継続して呼び出して、完了したことがわかるまで別のバッファに追加します。

編集例: あなたが探しているのは、ノンブロッキングIOです。それを実装する方法の1つは、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

ジェイ、私はあなたの考えを自分のコードの基礎として使い、今朝クライアントとテストします。私はこれを答えて、必要に応じて更新します。助けてくれてありがとう。 –

関連する問題