2010-01-03 52 views
1

我想要一些帮助以下。这与异步套接字有关。C#void ReceiveData(IAsyncResult iar)

从发件人:

string stringData = "Welcome to my server server server"; 
byte[] message1 = Encoding.ASCII.GetBytes(stringData); 

//MessageBox.Show(message1.Length.ToString()); 

client.BeginSend(message1, 0, message1.Length, SocketFlags.None, new AsyncCallback(SendData), client); 

这里可以看出,该message.length可以找到。

- 在客户端上

Socket remote = (Socket)iar.AsyncState; 
    int recv = remote.EndReceive(iar); 
    string stringData = Encoding.ASCII.GetString(data, 0, recv); 

我的问题是有没有访问发送的数据的实际长度,并基于该呼叫收到数据的方式,直到完整的消息被收到?

回答

7

否 - TCP/IP是协议。仅仅因为你用一次呼叫发送数据并不意味着它将作为一个数据包发送,或者它不会与其他数据包合并。换句话说,发送“X”然后发送“Y”相当于发送“XY” - 它们可能以完全相同的数据包进行传输,与另一端无法区分。

如果您想在流中使用单个“消息”,您应该在数据前加上几个字节来明确指出其长度。 (另一种方法是使用分隔符,但我更喜欢使用长度前缀 - 这样可以更容易地知道您还需要接收多少数据,您无需担心开始使用下一条消息,你不必担心以某种形式逃避分隔符。)

+0

而不是前缀我刚刚实现了一个循环,如此处所述http://stackoverflow.com/questions/582550/c-begin-endreceive-how -DO-I-读大的数据。它似乎在工作! :) – iTEgg 2010-01-03 16:40:12

+0

如果您希望在套接字关闭之前接收所有数据,那么您只能保持循环,否则当您*实际*看到它时,您将无法知道。如果您只是在连接上执行单个请求/响应,那很好,但它不适用于每个方向都有多个消息的“对话”协议类型。 – 2010-01-03 16:48:29

0

只有当传送某些信息来传达长度时 - 或者将消息的长度预先保留,或者发送某种类型的终止符字符。