0

我已经编写了一个基于 Webdis 的简单 HTTP 服务器。现在我遇到了一个问题,当客户端发送 HTTP 请求而没有接收响应(AKA,只发送,不接收来自服务器的响应)时,服务器将收到多个 HTTP 请求,这将导致解析模块失败(可能这是解析模块中的错误)。如果有任何模糊,来我的一些代码:

/* client... */
int fd = connect_server();
while (1) {
    send(fd, buf, sz);
    continue; /* no receive.. */        
}

/* server... */
/* some event trigger following code */
char buffer[4096]; /* a stack based receive buffer, buggy */
ret = recv(fd, buffer, sizeof(buffer));

而客户端在服务器休眠期间发送 10 个 HTTP 请求(小于 4096 字节)(用于调试),下一次接收将接收 10 个请求,但解析器无法解析多个请求,这使得所有这些请求都失败。如果所有这些请求都大于 4096,这将切断其中一个并且仍然失败。

我浏览了Nginx源代码,可能是回调设计的(不是怪罪),我还没有得到它的解决方案......


有没有办法做以下事情:

如何控制recv一次只收到一个请求的呼叫?或者是否有一些与 TCP 相关的机制可以只接收一个send请求?

4

2 回答 2

1

TCP 根据定义是基于流的,因此您永远无法保证消息边界会被重划。严格来说,TCP中不存在这样的东西。但是,使用阻塞套接字并确保禁用 Nagle 算法,可以减少每个 recv() 包含多个段的机会。只是为了测试,您还可以在每个 send() 之后插入一个睡眠。你也可以玩弄 TCP_CORK。

但是,我建议您实施“正确”接收,而不是一起破解某些东西,因为您必须在某些时候这样做。对于每个 recv 调用,检查缓冲区是否包含 HTTP 请求的结尾 (\r\n\r\n),然后进行处理。

于 2013-05-28T06:01:58.603 回答
1

这与同步性或事件无关,而是与此类套接字的流性质有关。必须缓冲先前接收到的数据,并且您必须完整地实现 HTTP 的某些部分,以便能够将传入请求标记为完成,之后您可以将其从缓冲区中释放并开始解析它。

于 2013-05-28T06:00:55.377 回答