1
有我做的简单的套接字程序(服务器/客户端)。 服务器正在运行的Windows和客户端是Android应用程序,其中包含由c socket构成的共享库。getpeername无法识别连接建立
在客户端,为了避免冻结,我将套接字更改为NON_BLOCK,而不是在传递connect()函数后回滚到BLOCK套接字。之后,我搜索连接可用getpeername()。
如下...
flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags|O_NONBLOCK);
nRet = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
if (nRet < 0)
if (errno != EINPROGRESS && errno != EWOULDBLOCK)
return ERR_CONN;
...
...
nRet = select(sock+1, &readset, &writeset, NULL, &tv);
if (nRet == 0)
if (errno != EINPROGRESS && errno != EWOULDBLOCK)
return ERR_SELECT;
nRet = getpeername(sock, (struct sockaddr*)&addr, &len);
if (nRet != 0)
return ERR_GETPEER;
fcntl(sock, F_SETFL, flags);
一切都运作良好。除了在3G模式下工作。
有时即使服务器得到连接,客户端返回getpeername()中的错误。 错误代码是ENOTCONN。
我该如何实施以避免这种情况?任何建议,将不胜感激。 thx提前。
我发现有什么问题。
首先,我应该在返回之前传递connect()之后回滚到BLOCK套接字。第二,似乎select()并不保证为timeval保留,所以我做了像GetTickCount()的函数,而不是计算时间来打破循环。
这是我的解决方案。
fcntl(O_NONBLOCK);
connect();
fcntl(BLOCK);
while (true)
{
fd_set rdfs, wdfs;
FD_ZERO(&rdfs); FD_ZERO(&wdfs);
FD_SET(sock, &rdfs); FD_SET(sock, &wdfs);
tv.tv_sec = 0; tv.tv_usec = 100;
nRet = select(sock + 1, &rdfs, &wdfs, NULL, &tv);
if (nRet == -1) return -1;
else if (nRet)
{
nRet = getpeername();
if (!nRet)
break;
}
if (get_tick_count() - delay > timeout)
return -2;
}
thx! sarnold,咖啡馆:)
没有你的'选择(2)'实际上返回'sock'在' readset'?你的意思是 – sarnold
,我查了FD_ISSET吗?对不起,我的可怜的英语:(如果是这样,不,不,我没有检查FD_ISSET getpeername之前 – JayMuzie
是的,就是这样;你应该只尝试读出类似于'FD_ISSET(3 )'为你的'readset'输出变量。 – sarnold