【问题标题】:Can't get return value after socket accept()套接字接受()后无法获得返回值
【发布时间】:2015-12-08 03:23:46
【问题描述】:

我有一个客户端/服务器程序。客户端运行良好。但是当客户端收到 10060 错误时,服务器似乎卡在 accept() 并且无法获得返回值。我怎样才能解决这个问题?我需要 accept() 返回一个错误,以便服务器可以继续做其他事情。

客户端代码:

SOCKET sock, sendrecv;  
sendrecv = myInitClientSocket(szIP, 6666);
if ( sendrecv ==0 ){  //socket 10060 error so that myInitClientSocket returns 0
    int err= WSAGetLastError();
    shutdown(sendrecv, 0x02);
    closesocket(sendrecv);
    return 0;
}       

服务器代码:

SOCKET sock, sendrecv;
struct sockaddr_in sock_addr,sendrecv_addr;
WSADATA data;
WORD p;
p=MAKEWORD(2,2);
int resStartup = WSAStartup(p,&data);
sock = WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0);
int nREUSEADDR = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&nREUSEADDR,sizeof(int)); 

sock_addr.sin_family=PF_INET;
sock_addr.sin_port=htons(6666);         
sock_addr.sin_addr.s_addr=INADDR_ANY;
int resBind =   bind(sock,(struct sockaddr*)&sock_addr,sizeof(struct sockaddr_in));
int resListen =listen(sock, 5); 
int lun = sizeof (struct sockaddr);
sendrecv = accept(sock,(struct sockaddr*)&sendrecv_addr,&lun);  //stucking here 
if(sendrecv == INVALID_SOCKET  )   
{
    //can't go in here
    return 5 ;
}

【问题讨论】:

  • 错误 10060 表示尝试连接服务器失败,例如,因为网络关闭或被防火墙阻止。服务器无法知道客户端正在尝试连接,所以accept()仍在等待连接。
  • accept 一旦有连接就返回,并且您的客户端没有连接(因为一些错误导致它无法连接)。你期待会发生什么?
  • @HarryJohnston 在这种情况下,我需要一种机制来处理这种情况。例如,10分钟后服务器将停止接受,返回一个值并做其他事情。
  • @immibis 好吧,我希望服务器可以停止等待连接并做其他事情。
  • 另外,我在这里实际上没有看到问题。

标签: c windows sockets


【解决方案1】:

accept 调用无法返回值,因为该调用应该阻止进程的执行并等待客户端到达。如果您什么都不做并且客户端没有出现,accept 将不会永远返回。

这里需要的是

  1. accept 之前使用select 查看是否有可用的待处理客户端。

  1. 使用setsockopt 设置SO_SNDTIMEO 和/或SO_RCVTIMEO 选项,使accept 在一段时间后退出,甚至立即退出。

实施细节可以在这里找到:How to accept socket with timeoutSetting Socket Timeout?

【讨论】:

  • 我在 accept() 之前使用 select()。它完美无缺!谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-11-22
  • 1970-01-01
  • 2012-09-14
  • 2023-03-09
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多