2016-04-12 15 views
0

ソケットを介して通信するクライアント/サーバーアプリケーションを作成しようとしています。しかし、私がデータを受け取ったとき、ランダムに混乱し、は常に(時には)正しいデータを表示しません。私がデータを受け取るために使用するコード:C#ソケット受信データが壊れる

private static void ReceiveCallback(IAsyncResult AR) 
{ 
    try 
    { 
     Socket socket = (Socket)AR.AsyncState; 
     if (SocketConnected(socket)) 
     { 
      int received = socket.EndReceive(AR); 
      byte[] dataBuf = new byte[received]; 
      Array.Copy(_buffer, dataBuf, received); 
      string text = Encoding.ASCII.GetString(dataBuf); 
      if (!text.Contains("GET") && !text.Contains("HTTP") && text != null) 
      { 
       Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + ":" + text); 
      } 
      socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket); 
     } 
     } 
     catch 
     { 

     } 
} 

私はこれがなぜ起こったのか誰かが説明できますか?前もって感謝します!

また、私はキャラクター(すべてのレスポンス ' - 'の終わりにありますが動作しませんでした)が見つかるまでチェックしようとしました。 Unfortunatleyこれは結果でした:Output

+0

方法:.NETの世界でフォーマットをエンコードする文字を使用すると、ASCIIの代わりにあなたがUnicodeに受信バイトを変換する必要があり、「ユニコード」です。コールバックと同じメソッドを呼び出します。コードの構造をより多くのメソッドに分割し、開始と終了の呼び出しを別々に処理する方が良いでしょう。コードがより構造化されていれば、ここで問題をデバッグするのに役立ちます。 – ManoDestra

+0

EndReceiveの後にBeginReceiveを取得しませんでした。それは機能しますか? – devprashant

答えて

1

あなたはHTTPのようなものを扱っているので、ソケットがTCPソケットであると仮定します。

TCPはメッセージではなくストリームを処理します。だから、あなたがあなたの読書をするときには、最大で_buffer.Lengthバイトがストリームから読み込まれます。つまり、応答の一部だけを簡単に読み取ることができます。応答が複数のコールバックに分割されます。あなたが偶然に十分に読むと、すべてが期待通りに機能します。これは、Windowsがlocalhost TCPを非localhostの場合と非常に異なる方法で扱うため、localhostでテストする場合に特に当てはまります。しかし、あなたがである場合、が十分に読み込まれない場合、textには完全な応答が含まれず、データが破損します。

さらに、receivedがゼロの場合、もう一方の側がストリームを閉じたことを意味します。BeginReceiveを停止する必要があります。

+0

私はあなたが意味することを理解していますが、私は可能な解決策を見つけることができません。ありがとうtho! –

1

メッセージ全体を受け取るまで、ソケット受信をループする必要があります。

これはまた、アプリケーションレベルのプロトコルが必要であることを意味します。メッセージを定義するものは何ですか?

終了文字?その後、その文字を取得するまで、読み取りをループします。

文字数?その後、多くの文字を取得するまで、ループを繰り返します。

メッセージの長さはメッセージの前にありますか?その後、長さを取得するのに十分なバイト数が得られるまでループし、メッセージ全体を取得するまでループします。

+0

サーバーはすべてのクライアントにコマンドを送信し、クライアントは応答を送信します。私は終了文字を追加しようとしましたが、それは私のために働かなかった(私は元の投稿を編集しました)また、文字の数は常にオプションではないので同じではありません。 –

0

あなたのソケットコードは私にはうまく見えます。構造化されている方法は、奇妙で受信開始および終了あなた

string text = Encoding.Unicode.GetString(dataBuf); 
+0

送信者が使用したのと同じエンコードを使用する必要があります。それが不明な場合は、仕様を尋ねるか、ご相談ください。あなたが失敗したときだけ推測を使用してください。 –

関連する問題