64b*_*uid 2 sockets linux message tcp recv
我正在尝试在Linux上创建一个p2p应用程序,我想尽可能高效地运行它.
我遇到的问题是管理数据包.我们知道,recv()缓冲区中可能随时有多个数据包,因此需要使用某种消息成帧系统来确保多个数据包不被视为一个大数据包.
所以目前我的数据包结构是:
(u16int Packet Length):(Packet Data)
Run Code Online (Sandbox Code Playgroud)
这需要两次调用recv(); 一个获取数据包大小,一个获取数据包.
这有两个主要问题:
1. A malicious peer could send a packet with a size header of
something large, but not send any more data. The application will
hang on the second recv(), waiting for data that will never come.
2. Assuming that calling Recv() has a noticeable performance penalty
(I actually have no idea, correct me if I am wrong) calling Recv() twice
will slow the program down.
Run Code Online (Sandbox Code Playgroud)
为最佳效率和稳定性构建数据包/接收系统的最佳方法是什么?其他应用程序如何做到这一点?您有什么推荐的吗?
先感谢您.
我认为你在TCP流中对消息的"框架"是正确的.
您可以考虑在每个帧的前面放置一个"魔术cookie"(例如,除了数据包长度之外,在每个帧头的顶部写入32位int"0xdeadbeef"),这样很明显你正在读取一个帧每个recv()对的第一个标题.它在消息开头没有出现魔术整数,你已经不同步,需要断开连接.
多次recv()调用可能不会受到性能影响.事实上,由于TCP消息可以以不可预测的方式进行分段,合并和停顿,因此您可能需要在循环中调用recv(),直到获得所需的所有数据.这包括您的两个字节标头以及有效负载字节的较大读取.完全有可能使用2字节缓冲区调用"recv"来读取消息的"大小",但只返回1字节.(再次调用recv,你将得到后续的字节).我告诉团队中的开发人员 - 对网络解析器进行编码,就好像recv一次只能传送1个字节一样.
您可以使用非阻塞套接字和"选择"调用来避免挂起.如果数据未在合理的时间内到达(或者数据到达的数量超出预期 - 这样就无法同步下一条消息),您只需断开连接即可.
我正在研究自己的P2P项目.愿意交易票据.如果你愿意,可以离线关注我.
| 归档时间: |
|
| 查看次数: |
2915 次 |
| 最近记录: |