繁体   English   中英

使用TCP套接字发送数据时是否必须对大数据进行分块?

[英]Do I have to chunk large data while sending it with tcp socket?

我通过TCP套接字发送一些不大字符串。 今天,我发送2031个字节,而接收端却一无所获(我已经发送了更大的消息-在2040个字节之前到几天前)-这还不是很糟糕,程序知道出了点问题,然后再次发送数据(第三次尝试成功)。 现在,我想知道是否应该将消息拆分为较小的块并在循环语句中发送它们? 我的代码中是否缺少某些内容?

Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,0);
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket,SocketOptionName.SendTimeout,0);           
LingerOption lingerOption = new LingerOption (true, 1); 
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket,SocketOptionName.Linger, lingerOption );
sock.Blocking =  true;

try
{
    sock.Connect(_dostHostEp);
}
catch(SocketException e)                     
{                                       
    sock.Close();
    throw new Exception("Connection error (" + _dostHostEp.Address + ":" + _dostHostEp.Port + ")" + e.Message);             
}

try    
{
    sock.Send(Encoding.UTF8.GetBytes(message));                             
}
catch(SocketException e)
{                   
    sock.Close();               
    throw new Exception("Error while sending message to (" + _dostHostEp.Address + ":" + _dostHostEp.Port + ")" + e.Message);               
}

为什么要坚持将2031字节分成一个块? 相反,您必须在接收方读取数据, 直到数据存在。 这意味着,例如,您读取了一个1800字节的块,另一个231字节的块,然后读取了0字节,这意味着数据结束。

我一直考虑在没有明确定义结束字符的情况下发送数据是一种不好的做法。 我个人建议执行以下操作:

作为发件人,在邮件前添加STX字符(0x02),并附加ETX字符(0x03)。

接收者应将STX识别为新消息的开始,然后读取(阻止?),直到接收到ETX。 如果在合理的时间内未收到任何ETX,则说明读取整个消息时出现问题。

您不需要使用STX和ETX,也可以使用\\ r \\ n或不属于消息本身的任何内容。

如果您没有使用定义良好的消息结尾,则读者将永远不知道何时停止阅读,并且会弄乱您的交流。

我确定有问题的一个示例案例:

发送者一个接一个地发送两个消息。 如果没有EndOfMessage字符,则接收方将尝试将其作为一条消息读取。 借助EOM,接收方可以拆分两个消息并同时处理它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM