C 当客户端连接但不发送数据时,该怎么办?

C 当客户端连接但不发送数据时,该怎么办?,c,linux,sockets,C,Linux,Sockets,我正在用C语言编写自己的web服务器,我被一个恼人的问题困扰着。 我正在等待这样的传入连接: struct sockaddr_in caddr; uint32_t caddr_len = sizeof(caddr); int fd = accept(sfd, (struct sockaddr *)&caddr, &caddr_len); if(fd < 0) { err(EXIT_FAILURE, "accept()"); } 有时,当使用fire

我正在用C语言编写自己的web服务器,我被一个恼人的问题困扰着。 我正在等待这样的传入连接:

struct sockaddr_in caddr;
uint32_t caddr_len = sizeof(caddr);
int fd = accept(sfd, (struct sockaddr *)&caddr, &caddr_len);
if(fd < 0) {
  err(EXIT_FAILURE, "accept()");
}
有时,当使用firefox访问时,我没有收到任何数据。 当我将超时设置为1s时,
errno
设置为
EAGAIN
。 当我将超时设置为5s时,
errno
将不会被设置,但我仍然没有收到任何数据
r==0

是否可以配置套接字,使
accept()
仅在有实际数据可用时返回

注意:使用Chrome访问时,我没有经历过这种行为

编辑:一些人建议我应该使用
poll()

当我使用
poll()
时,我遇到了相同的问题:

struct pollfd p[] = {{sfd, POLLIN}};
int r = poll(sfd, 1, 1000);
if(r <= 0) err("poll() -> %d", r);
struct pollfd p[]={{sfd,POLLIN};
INTR=投票(sfd,11000);

if(rAccept在连接被接受时返回。如果要等到数据可以读取,则需要使用or(或阻塞)。

Accept在连接被接受时返回。如果要等到数据可以读取,则需要使用or(或阻塞).

您可以使用
选择
轮询
或类似方法。请参阅:

您可以使用
选择
轮询
或类似方法。请参阅:

当我使用poll()时,我也遇到了同样的问题,因为它告诉我的是,有一个客户端需要连接。我需要的是:(需要连接并具有有效负载)@Cosinus将新连接的
fd
添加到
poll
/
选择
参数,然后再次等待。@alagner这正是我试图避免的,因为firefox正在阻止我的runnier,直到超时发生。在此期间,这个运行程序可能已经处理了来自其他客户端的多个请求。@Cosinus不知道你到底是如何处理的g多个客户端,但底线是:连接和发送是两种不同的操作。您可以
选择
/
轮询
/
将您的异步调用放在所有连接的客户端上,并仅处理当前发送的客户端。另一种选择是使用多线程/multprocessed服务器。但这一切真正取决于您到底在做什么。@Cosinus:您想要的是不可能的,因为客户端是否要连接是侦听套接字的属性,而负载是否可读取是已连接套接字的属性。在您调用accept并返回之前,连接的套接字不存在。要按您的要求执行操作,请执行以下操作:king将需要向内核添加另一个系统调用,以便能够查询未被接受的连接上是否有数据可用,而该连接还没有套接字。当我使用poll()时,我会遇到同样的问题,因为它告诉我的是,有一个客户端需要连接。我需要的是:(希望连接并具有有效负载)@Cosinus将新连接的
fd
添加到
poll
/
选择
参数,然后再次等待。@alagner这正是我试图避免的,因为firefox正在阻止我的runnier,直到超时发生。在此期间,这个运行程序可能已经处理了来自其他客户端的多个请求。@Cosinus不知道你到底是如何处理的g多个客户端,但底线是:连接和发送是两种不同的操作。您可以
选择
/
轮询
/
将您的异步调用放在所有连接的客户端上,并仅处理当前发送的客户端。另一种选择是使用多线程/multprocessed服务器。但这一切真正取决于您到底在做什么。@Cosinus:您想要的是不可能的,因为客户端是否要连接是侦听套接字的属性,而负载是否可读取是已连接套接字的属性。在您调用accept并返回之前,连接的套接字不存在。要按您的要求执行操作,请执行以下操作:king将需要向内核添加另一个系统调用,以便能够查询尚未具有套接字的未接受连接上是否存在可用数据。我找到了解决方案。
poll()
可以同时观察多个
fd
。因此,我将第一个条目用于侦听fd(
sfd
).如果有更改,我将调用
fd=accept(sfd)
并将新的
fd
放入相同的观察列表中。当新创建的
fd
s之一发生更改时,我知道此fd有数据。不清楚如何将超时设置为…,以及如何知道发生了超时。这就是我们询问示例的原因。请参阅前面引用的页面,并编辑您的用这样一个完整且可验证的例子提问。我找到了解决方案。
poll()
可以同时观察多个
fd
s。因此,我使用第一个条目作为侦听fd(
sfd
)。如果有一些更改,我将调用
fd=accept(sfd)
并将新的
fd
放入相同的观察列表中。当新创建的
fd
s之一发生更改时,我知道此fd有数据。不清楚如何将超时设置为…,以及如何知道发生了超时。这就是我们询问示例的原因。请参阅前面引用的页面,并编辑您的用这样一个完整的、可验证的例子提问。
struct pollfd p[] = {{sfd, POLLIN}};
int r = poll(sfd, 1, 1000);
if(r <= 0) err("poll() -> %d", r);