2016-11-19 9 views
-2

cのソケットに2つの部分で私の受信データsliptは、データを受信します私は、サーバーアプリケーションとして、このコードを持っている#

public AsyncCallback pfnWorkerCallBack; 
private Socket m_mainSocket; 
private Socket[] m_workerSocket = new Socket[25]; 
private int m_clientCount = 0; 
public void startfun() 
{ 
    string Camera1Port = "1001"; 

    int port1 = System.Convert.ToInt32(Camera1Port); 

    m_mainSocket = new Socket(AddressFamily.InterNetwork, 
             SocketType.Stream, 
             ProtocolType.Tcp); 
    IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port1); 
    m_mainSocket.Bind(ipLocal); 
    m_mainSocket.Listen(20); 
    m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); 
} 
public void OnClientConnect(IAsyncResult asyn) 
{ 
    m_workerSocket[m_clientCount] = m_mainSocket.EndAccept(asyn); 

    WaitForData(m_workerSocket[m_clientCount]); 

    ++m_clientCount; 

    m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); 
} 
public class SocketPacket 
{ 
    public System.Net.Sockets.Socket m_currentSocket; 
    public byte[] dataBuffer ; 
} 
public void WaitForData(System.Net.Sockets.Socket soc) 
{ 

    if (pfnWorkerCallBack == null) 
    { 
     pfnWorkerCallBack = new AsyncCallback(OnDataReceived); 
    } 

    SocketPacket theSocPkt = new SocketPacket(); 
    theSocPkt.dataBuffer = new byte[soc.ReceiveBufferSize]; 
    theSocPkt.m_currentSocket = soc; 

    soc.BeginReceive(theSocPkt.dataBuffer, 0, 
            theSocPkt.dataBuffer.Length, 
            SocketFlags.None, 
            pfnWorkerCallBack, 
            theSocPkt); 
} 

public void OnDataReceived(IAsyncResult asyn) 
{ 
    SocketPacket socketData = (SocketPacket)asyn.AsyncState; 
    string res = GetParameters(socketData.dataBuffer); 
    MessageBox.Show(res); 
    WaitForData(socketData.m_currentSocket); 
} 
public string GetParameters(byte[] buf) 
{ 
    string result = System.Text.Encoding.UTF8.GetString(buf); 
    return result; 
} 

問題は、データは、私が最初にソケットからデータを受信したとき.I意味破壊されていますすべての値が受信され、メッセージボックスにすべてのものが表示されます.2番目のデータが受信されると、ちょうどその一部が受信されます。データは870314854798です。最初のデータは正しく受信されますが、2番目には3または4桁(ランダム)で、メッセージボックスにok(メッセージボックス)をクリックした後に3桁または4桁の数字が表示されます。他の数字が表示されます。

私はそれをGoogleで検索し、私はこれを見つけたが、私は私の解決策

public static void Read_Callback(IAsyncResult ar){ 
    StateObject so = (StateObject) ar.AsyncState; 
    Socket s = so.workSocket; 

    int read = s.EndReceive(ar); 

    if (read > 0) { 
      so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read)); 
      s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, 
            new AsyncCallback(Async_Send_Receive.Read_Callback), so); 
    } 
    else{ 
     if (so.sb.Length > 1) { 
       //All of the data has been read, so displays it to the console 
       string strContent; 
       strContent = so.sb.ToString(); 
       Console.WriteLine(String.Format("Read {0} byte from socket" + 
           "data = {1} ", strContent.Length, strContent)); 
     } 
     s.Close(); 
    } 
} 

で、このソリューションをマッピングすることはできません問題は、私は私のコードでこのソリューションをマージすることができますどのようにでしょうか?

+0

どのプロトコルを使用しますか? TCPまたはUDP? TCPならば、それは正常です....あなたは3 + 3バイトを送って6を得るか、6を送って4 + 2を得ることができます。*パケットを受け取るためにカスタム*プロトコル*を実装するべきです*(例えば、データの長さを前もって送信したり、セパレータ文字などを使用するなど) –

+0

@LB私のprotpcolはtcp –

+0

です[Edwardの回答](http://stackoverflow.com/a/40697769/80274)既にこれをカバーしていますかなりうまくいっていますが、[ここでは問題の参考になる参考文献があります](http://blog.stephencleary.com/2009/04/message-framing.html)、何らかのメッセージフレーミングをする必要があります。 –

答えて

1

。それ以外の場合は、例外が発生しないことがあります。

+0

ここにarは何ですか? –

+0

申し訳ありませんがタイプミスです。私は編集をしましたが、それは非同期であったはずです – CodingYoshi

+1

@EhsanAkbarこの答えは正しいことを言っていますが、あなたの問題は解決しません... 10Mのデータを一度に送信してみてください... * READ * –

1

これは、ネットワークスタック(特にTCP)がどのように機能するかを示しています。 1つのソケットとしてソケットに送信されるすべてのデータが単一の部品としてクライアントに配送されることを保証するものではありません。ソケットに送信されるすべてのデータは、クライアントが同じ順序で受信することが期待できますが、どのようにチャンクに分割されるかには依存できません。

など。データがネットワークを通って移動するとき、パケットがどれくらい大きくなるかについての異なる設定および制限を有するノードを通過する可能性がある。パケットが大きすぎる場合は、適切なサイズの複数のパケットに分割され、クライアントに送信されます。

あなたのプロトコルでは、サーバーからクライアントにパケットを1つのソリッドピースとして配信する必要がある場合は、それを制御する独自のアプリケーションレイヤプロトコルを構築する必要があります。これはhttpの仕組みです。ウェブページを表すデータがどのようにTCPパケットに分割されても、クライアントは一度にページ全体を受け取ります。

StateObject so = (StateObject) async.AsyncState; 
Socket s = so.workSocket; 

int read = s.EndReceive(async); // You need to do this. 

あなたは常にすべての非同期操作にEndInvokeをなど、MSDNの勧告に従って、EndReceiveを呼び出す必要があります:あなたはこのように始まった操作を完了するために、EndReceive必要がありますあなたのOnDataReceived方法で

関連する問題