Linux中的套接字 - 我怎么知道客户端已完成?

时间:2011-05-07 23:09:25

标签: c++ linux http sockets

我目前正在尝试用C ++实现自己的网络服务器 - 不是为了高效使用,而是为了学习。

我基本上打开一个套接字,监听,等待连接并打开一个新的套接字,我从中读取客户端发送的数据。到现在为止还挺好。但是,我怎么知道客户端已经完成了发送数据而不是因为其他原因暂时停止发送更多数据?

我当前的示例:当客户端发送POST请求时,它首先发送标题,然后连续两次“\ r \ n”,然后是请求正文。有时身体不包含任何数据。因此,如果客户端在发送标题后暂时无法发送任何内容 - 我怎么知道它尚未完成其请求?

这完全取决于所使用的协议(HTTP),我的任务是根据我收到的数据找出它,或者是否有类似EOF的套接字?

如果我无法从套接字获取必要的信息,如何保护我的程序免受故障客户端的影响? (我想我无论如何都必须这样做,因为它可能是攻击者而不是发送错误数据的错误客户端。)是我唯一的选择,通过定义协议或超时(由我到达了吗?

我希望这是有道理的。

顺便说一句:请不要告诉我使用某些图书馆 - 我想学习基础知识。

3 个答案:

答案 0 :(得分:1)

  

“这完全取决于使用的协议(HTTP),我的任务是根据收到的数据找出这个,”

正确。您可以通过谷歌找到HTTP规范; http://www.w3.org/Protocols/rfc2616/rfc2616.html

  

“或者是否有类似EOF for socket的东西?”

因为它的行为就像一个文件......但是这里不适用,因为客户端没有关闭连接;你在那个连接上发送了回复。

答案 1 :(得分:1)

协议(HTTP)告诉您客户端何时停止发送数据。您无法从套接字获取信息,因为客户端会将其保持打开状态等待响应。

正如您所说,您必须防止错误的客户未发送正确的请求。通常,在请求不完整的情况下,对读取应用超时。如果30秒内没有收到任何信息,请关闭套接字并忽略它。

对于HTTP帖子,应该有一个标题(Content-Length)表示标题结束后要预期的字节数。如果是POST并且没有Content-Length,则拒绝它。

答案 2 :(得分:1)

使用基于文本的协议(如HTTP),您将受到客户端的支配。格式最好的POST将具有内容长度,因此您可以知道将要传输多少数据。然而,客户端可能只是延迟发送数据,或者它可能已经移除了以太网电缆或只是挂起,在这种情况下,套接字无限期地位于那里。如果它很好地断开连接,那么你将从recv()获得一个套接字关闭事件/响应。

在这种情况下,大多数设计良好的服务器都会有一个接收超时,如果套接字空闲超过30秒,它将关闭该套接字,因此行为不当的客户端不会泄露资源。