我正在使用C#开发服务器(使用* Async方法)。一切正常,直到一方违反协议(例如攻击服务器)。
客户端和服务器交换以下结构的消息:
如果有人传输错误的长度 - 此客户端与服务器之间的所有通信都变得不可预测。
因此,我们的想法是以最简单的方式创建自同步协议。
我正在使用TCP协议,因此想法是将消息分解为数据包,并且没有两个消息应该共享相同的数据包 - 这样我就能够忽略协议违规并恢复通信,如果有的话错。
我想使用TCP,因此数据包将与TCP段相同。但捕获量很少:
我是套接字服务器编程的新手,所以我需要帮助。也许有人可以分享这个问题的常见解决方案(防错协议)或描述常见的陷阱,或者提供有用的链接。
我正在.NET下开发,如果可以避免,我不想使用任何P / Invokes。
答案 0 :(得分:2)
TCP抽象是流的抽象,没有内置的消息边界,你不应该试图违反抽象。
处理行为不端客户端的主要策略是严格检查客户端提供的所有输入(例如,通常在协议级别消息的允许大小上设置上限)。当完整性检查指示违反了协议时,您将停止处理错误消息。您可能还想记录错误,并/或将其报告给客户端。
如果协议违规使您无法重新同步,那么您别无选择,只能断开客户端连接。这可以;行为不端的客户无权期待任何服务水平。
您可以设计允许重新同步的协议 - 最简单的示例是在后续协议消息之间的边界处使用分隔符(不允许在消息中出现分隔符本身)。许多旧的“基于行”的互联网协议,如FTP,SMTP和IRC以这种方式工作(在这种情况下,分隔符是换行符)。
答案 1 :(得分:1)
这里有两个不同的问题。
通过在协议处理程序中构建错误更正,无法保护服务器安全。您需要安全的编码实践来做到这一点。查看启动器的SSL - 如果你试图让服务器全部安全a)它将不会,并且b)它将花费很长时间。
您可能会发现,一旦服务器安全,协议错误的问题就很容易解决。这意味着客户端上的编码错误或网络数据完整性问题。排除前面的恶意使得任何一个问题都更容易解决。
答案 2 :(得分:0)
您可能想了解the protobuf-c RPC implementation:
客户端发出一个12字节的头,后跟protobuf编码的消息有效负载:
- 方法索引(编码为4字节小端数字)
- 消息长度:protobuf编码的有效负载的长度(编码的4字节little-endian)
- 请求ID:客户端选择的值,以允许它在多个未完成请求的情况下知道哪个服务器响应对应于哪个请求。 (以4个字节编码)
服务器最终会发出类似的16字节响应:
- 状态代码(作为4字节的小端数字)。以下值之一:
0:成功
1:服务失败(即传递NULL为消息到闭包)
2:待处理的太多(客户端连接有太多未决请求)
- 方法索引(与请求相同)
- 消息长度(与请求相同)
- 请求ID(与请求相同)
要考虑添加的另一件事,如果您尝试通过非TCP / IP(即无错误的通道)执行此操作,则需要在标头和有效负载上添加CRC检查。
答案 3 :(得分:0)
断开行为不端的客户