插座选择失败,并在正在进行的操作 - 非阻塞模式 [英] socket select fails with operation in progress - Non blocking mode
问题描述
我们的应用程序使用与连接和选择操作(C code)一个非阻塞套接字的使用。
该pusedo code是如下
Our application uses a non-blocking socket usage with connect and select operations (c code). The pusedo code is as below
unsigned int ConnectToServer(struct sockaddr_in *pSelfAddr,struct sockaddr_in *pDestAddr)
{
int sktConnect = -1;
sktConnect = socket(AF_INET,SOCK_STREAM,0);
if(sktConnect == INVALID_SOCKET)
return -1;
fcntl(sktConnect,F_SETFL,fcntl(sktConnect,F_GETFL) | O_NONBLOCK);
if(pSelfAddr != 0)
{
if(bind(sktConnect,(const struct sockaddr*)(void *)pSelfAddr,sizeof(*pSelfAddr)) != 0)
{
closesocket(sktConnect);
return -1;
}
}
errno = 0;
int nRc = connect(sktConnect,(const struct sockaddr*)(void *)pDestAddr, sizeof(*pDestAddr));
if(nrC != -1)
{
return sktConnect;
}
if(errno != EINPROGRESS)
{
int savedError = errno;
closesocket(sktConnect);
return -1;
}
fd_set scanSet;
FD_ZERO(&scanSet);
FD_SET(sktConnect,&scanSet);
struct timeval waitTime;
waitTime.tv_sec = 2;
waitTime.tv_usec = 0;
int tmp;
tmp = select(sktConnect +1, (fd_set*)0, &scanSet, (fd_set*)0,&waitTime);
if(tmp == -1 || !FD_ISSET(sktConnect,&scanSet))
{
int savedErrorNo = errno;
writeLog("Connect %s failed after select, cause %d, error %s",inet_ntoa(pDestAddr->sin_addr),savedErrorNo,strerror(savedErrorNo));
closesocket(sktConnect);
return -1;
}
.
.
.
.
.}
问题陈述结果
在上面的code时,选择
失败错误code 115
这是工作正在进行中。我没有看到任何文件,选择
与错误号115
失败。
Problem statement
In the above code, the select
fails with error code 115
which is "Operation in progress". I do not see any documentation on select
failing with errno 115
.
一个。什么时候选择
失败错误code 115
在非阻塞套接字?在什么样的情况?结果
湾我们看到的这暗示了该问题的系统日志。只是我们关注我 - 我无法找到任何记录功能,它描述了这样的问题。
a. When does the select
fails with error code 115
in non-blocking socket? Under what scenario?
b. Do we see any system logs which hints at this problem. Only concern for us me - I could not find any documented feature which describes such problem.
PS:我们正在使用的SUSE Linux 11企业版
PS : We are using SUSE Linux 11 Enterprise Edition.
推荐答案
的 在code的几点思考:的搜索
Some thoughts on your code:
我想下面的选择你的条件可以修改为只检查,看看,如果选择返回的值大于0,如果是这样的话,你可以检查的getsockopt的输出插座(为SOL_SOCKET和SO_ERROR)选项(的getsockopt(... SOL_SOCKET,SO_ERROR,...,...)
)查看是否连接还没有失败。
I think your condition below the select can be modified to check only to see, if select has returned a value greater than 0 and if that is the case, you can check output of getsockopt for the socket (for SOL_SOCKET and SO_ERROR) options (getsockopt(...,SOL_SOCKET, SO_ERROR,...,...)
) to see if connect has not failed.
我不是很肯定,如果选择将始终返回插座为可写在连接成功的情况下。所以,你的情况,它可能(只可以)是,TMP变量不是-1,它是显示错误号是previous的连接调用错误号的情况。
I am not very sure if the select will always return the socket as writable in case of a connection success. So, in your case, it may (only may) be the case that, the tmp variable is not -1 and the errno it is showing is the errno of the previous connect call.
的 其他原因:的
Additional Reasons:
另一个很好的理由是,目的地址为您正在连接要么无法访问,或者没有一个服务器在指定的地址+端口的组合等。在这种情况下,你可以用一个阻挡套接字一次尝试,看看是否能连接。
Another good reason is that, the destination address to which you are connecting is either not reachable, or doesn't have a server waiting at the specified address + port combination. In which case, you can try once with a blocking socket to see if that connects.
这篇关于插座选择失败,并在正在进行的操作 - 非阻塞模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!