2011-05-07 37 views
0

我目前正试图在C++中实现我自己的Web服务器 - 不是为了生产性使用,而是为了学习。Linux中的套接字 - 我如何知道客户端已完成?

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

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

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

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

我希望这是有道理的。

顺便说一句:请不要告诉我使用一些库 - 我想了解基础知识。

回答

1

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

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

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

+0

谢谢。这意味着我目前的“解决方法”实际上是要走的路。 :-) – sirion 2011-05-07 23:34:20

1

“这是否完全取决于所使用的协议(HTTP),这是我的任务是找出这我接收到的数据的基础上,”

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

“或者是否有类似插座的EOF?”

它的行为就像一个文件...但这不适用于此,因为客户端没有关闭连接;你正在发送该连接的答复。

+0

并非完全如此。客户端可以使用例如半关闭连接来关闭连接。关掉()。在这种情况下,服务器在从套接字读取时获取EOF状态,但仍然可以写入套接字。 – 2011-05-07 23:25:56

+0

这将违反HTTP 1.1规范,它说客户端应该保持持久连接。 – 2011-05-07 23:34:29

+0

RFC有关* server *的说法*保持持久连接。我不认为RFC2616中有任何东西阻止客户端关闭连接,当没有更多需要发送的时候。 – 2011-05-07 23:46:12

1

使用基于文本的协议(如HTTP),您将受到客户端的支配。大多数格式良好的POST都会有一个内容长度,以便知道有多少数据即将到来。然而,客户端可能会延迟发送数据,或者它的以太网电缆可能已被移除或挂起,在这种情况下,该套接字将无限期地放置在那里。如果它很好地断开连接,那么你会从recv()中得到一个套接字关闭事件/响应。在这种情况下

最精心设计的服务器将有一个接收超时,如果插座是闲置超过说30秒钟,这两点将会关闭套接字,所以资源不被行为不端的客户端泄露。

相关问题