2009-05-08 8 views
1

私は一連のメッセージを受信して​​いるコードのこのビットを持っている:ソケットは、メッセージのみのC#の一部を受け取る

byte[] buffer = new byte[10240]; 
//... 
sock.Receive(buffer); 
string response = message(buffer); 
Console.WriteLine("Message Recieved"); 
if (!verifyUser(response, sock)) 
Console.WriteLine("User Invalid"); 
//... 
static private bool verifyUser(string userString, Socket sock) 
{ 
    string[] userData = userString.Split(' '); 
    int i = 0; 
    while (true) 
    { 
     if (userData[0].ToUpper() != "USER") 
     { 
      byte[] buffer = message("WHO"); 
      sock.Send(buffer); 
      userData = userString.Split(' '); 
      i++; 
      if (i > 4) 
      { 
         return false; 
        } 
        continue; 
       } 
       else 
        break; 
      } 
Console.WriteLine("Connection recieved from " + userData[1] + " with hash of "/* + userData[2]*/); 
} 

私がいる問題は、私は、すべてのユーザー名unkwntechを提出する場合にそれを表示し得ることですunkwnt、そして2番目の値はそこに到達することは決してありません。データを送信する アプリは次のようになります。

static void Main(string[] args) 
     { 
      Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
      EndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 200); 
      sock.Connect(remoteEP); 
      byte[] buffer = Encoding.ASCII.GetBytes("USER unkwntech a3f5h4a35sfg");//Made up hash 
      sock.Send(buffer); 
      sock.Receive(buffer); 
      Console.WriteLine(Encoding.ASCII.GetString(buffer)); 
      Console.ReadLine(); 
     } 
+0

「メッセージ」機能の定義を表示できますか?アプリケーションをデバッグしましたか?データが失われるのはいつですか? –

答えて

7

あなた、あなたが送信すると、すべてのデータは、単一のパケットで終わることを想定しだと、あなたは一度にすべてのデータを受信しますことをもう片方に。それはTCP/IPの仕組みではありません。これはストリーミングプロトコルです。一度に受信するデータの量を決して仮定しないでください。

基本的には、すべてのデータを読み、ソケットが閉じられているか、「十分な」データが得られるまで、ストリームから読み込む必要があります。プロトコルを制御しており、会話型プロトコルであれば、送信する各メッセージの先頭にプレフィックスが付いていればもっと簡単になります。つまり、相手方は予想するデータの量を知ることができます。

1

Socket.Receive呼び出しの戻り値を確認します。受信したバイト数を返します。この呼び出しをループに入れ、期待するバイト数が得られるまで読み込むことができます。また、最大試行回数を設定するか、またはJohnが示唆したように、ソケットの状態をチェックすることで、無限ループを防ぐ必要があります。また、戻り値が0であると仮定しても、メッセージ全体を読み取ったとは限りません。

あなたのプロトコルの長さがプレフィックスされた各メッセージを持っている場合、本当に防御的であるように、プロトコルはプレフィックス長ヘッダーの終わりを示すマーカーバイトも定義する必要があります。マーカーバイトが表示されるまで、一度に1バイトずつ読み取ります。次に、メッセージの長さを計算し、それをすべて読んだら、大きな塊を読み込みます。

Socket.Receiveは、受信するバイト数を指定できるオーバーロードを定義します。 (ただし、その多くを受け取ることは保証されていないので、戻り値を確認する必要があります)。

関連する問題