gpt4 book ai didi

android - getpeername 无法识别已建立的连接

转载 作者:太空宇宙 更新时间:2023-11-04 04:55:52 27 4
gpt4 key购买 nike

我做了一个简单的套接字程序(服务器/客户端)。服务器在 windows 上运行,客户端是 android 应用程序,其中包含由 c 套接字组成的共享库。

在客户端,为了避免卡住,我将套接字更改为 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。

我应该采取什么措施来避免这种情况?任何建议将不胜感激。提前致谢。


我发现了问题。

首先,我应该在通过 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;
}

谢谢!萨诺德,咖啡馆 :)

最佳答案

判断socket是否连接,更常用的是getsockopt()而不是getpeername():

int so_error;
socklen_t len = sizeof so_error;

getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);

if (so_error == 0) {
/* socket is connected */
}

关于android - getpeername 无法识别已建立的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8145624/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com