这是我多年来一直怀疑的问题。
这是我的情景。通过无线连接到网络的笔记本电脑上托管的聊天服务器。现在每个客户端始终请求并发送服务器必须解析的数据。平均数据包看起来像:
REQ_RM_LST|InfoHere
或者
CLI_LIST|NameHere|NameHere|NameHere|NameHere|NameHere|NameHere|NameHere
这会弄乱服务器吗?如同,导致数据包丢失,数据丢失,数据包/请求甚至没有被解析?如果是这样,将连接多少客户端并发送不同长度的类似数据以产生这些问题?
谢谢!
答案 0 :(得分:4)
平均数据包看起来像:
不,他们没有;有两个原因:
这会弄乱服务器吗?
没有;为什么会这样?
如同,导致数据包丢失,
在网络层,这是TCP实现;只要您的NIC /驱动程序是理智的。在应用程序层:这取决于您的代码。
数据丢失,数据包/请求甚至没有被解析?
再次,直到您的代码
如果是这样,有多少客户端会连接并发送不同长度的类似数据以产生这些问题?
这不是客户数量的一个因素;如果您的代码有错误,那么无论连接了多少客户端,它都会出现错误。我的套接字服务器运行了数万个连接客户端很长一段时间 - 不是问题。 Stack Exchange网络的“实时更新”套接字服务器目前有126,815个连接套接字(分布在几个服务器上,但这主要用于部署的重复性 - 即使在单个服务器实例上也有很高的数量) - 并且已写入使用C#/ .NET套接字。
人们在套接字中犯的最常见的错误是希望发件人做:
Write({8 bytes});
...
Write({12 bytes});
...
Write({8 bytes});
并期望接收器获得 8,12,8字节。这不是发生的事情。它只是一个流。接收器可以一次获得所有28个字节,或者可以获得2个,10个,1,1,1个字节。这就是为什么你需要编写某种框架协议。对于基于文本的协议,这通常是“读取,直到获得标记值,例如表示换行符的字节”。对于基于二进制的协议(其中sentinel值没有意义),这通常是长度前缀,例如“前4个字节是一个小端编码的32位整数,表示后续有效负载的长度”(有很多其他编码方案可能,请注意)。
有关详情,请参阅http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html