如何使TCP接收处理异步(或无回声)客户端?

时间:2013-05-28 05:51:25

标签: http tcp nginx

我已经编写了一个基于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请求?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

然而,我不会一起黑客攻击,而是建议您实施接收"正确",因为您必须在某些时候执行此操作。对于每个recv调用,检查缓冲区是否包含HTTP请求的结尾(\ r \ n \ n \ n \ n \ n),然后进行处理。