connect非阻塞,send和recv是阻塞的,会影响发送和接收吗?

轻箬笠 2019-07-24 09:23:51
SOCKET/*int*/ sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sockfd < 0)
{
return;
}
struct sockaddr_in serv_addr;

//以服务器地址填充结构serv_addr
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(strIP);
serv_addr.sin_port = htons(nPort);
int iTimeOut = 3000;
setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));
setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));

int error = -1;
int len = sizeof(int);
timeval tm;
fd_set set;
unsigned long ul = 1;
ioctlsocket(sockfd, FIONBIO, &ul); //设置为非阻塞模式
bool ret = false;
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
{
tm.tv_sec = 3;
tm.tv_usec = 0;
FD_ZERO(&set);
FD_SET(sockfd, &set);
if( select(sockfd+1, NULL, &set, NULL, &tm) > 0)
{
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&error, /*(socklen_t *)*/&len);
if(error == 0)
ret = true;
else
ret = false;
}
else
ret = false;
}
else
ret = true;
ul = 0;
ioctlsocket(sockfd, FIONBIO, &ul); //设置为阻塞模式
if(!ret)
{
closesocket( sockfd );
fprintf(stderr , "Cannot Connect the server!/n");
return;
}

fprintf( stderr , "Connected!/n");

char buff[] = "hello";
int sl=::send(sockfd,(char*)buff, sizeof(buff), 0);
char buffer[512] = {0};
int ret = recv(sockfd, buffer, sizeof(buffer), 0);
closesocket( sockfd );


我的逻辑是这样的,设置接收和发送超时。考虑到connect在阻塞模式下,超时时间很长,设置为非阻塞模式,connect成功后,设回阻塞模式。但是测试情况来看,有大概20%的概率recv失败,有一部分错误码是10060(WSAETIMEDOUT 连接超时)。
这究竟是为什么?
...全文
245 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
轻箬笠 2019-07-30
  • 打赏
  • 举报
回复
最近几天都在做测试。还是没有太多的头绪。倒是发现,如果使用curl下载后,下载后马上测试网络ping值比下载前测试网络ping值要大蛮多的(我用的是tcping.exe),甚至有些用户的电脑,直接连不上下载服务器了(如果连接时间超过2s算连不上)。
通过curl的返回值,倒是找到一个相关的说法,"客户端的TIME_WAIT状态的socket进程过多,导致端口被占满"。https://www.cnblogs.com/jacklikedogs/p/4171361.html

目前没做类似TIME_WAIT监控和清理的工作,如果要做的话,是否可以给个例子?
另外,我个人比较好奇的,一个用户电脑,有可能出现大量TIME_WAIT状态的socket进程吗?本人的程序是短连接,不到10个吧。
赵4老师 2019-07-30
  • 打赏
  • 举报
回复
高度怀疑被攻击了。
林多 2019-07-24
  • 打赏
  • 举报
回复
WSAETIMEDOUT ,表明连接已经断开啦。看一下服务端,是不是TCP连接的keeplive之类的机制,Socket端一定时间不活动,资源就回收了。也可以抓包,看看,这个异常发生前,服务器端发了什么包。
sdghchj 2019-07-24
  • 打赏
  • 举报
回复
如果connect超时了,你又不return,后面的send、recv的意义在哪?不返回给你超时你想它返回给你什么?
引用 2 楼 轻箬笠 的回复:
[quote=引用 1 楼 sdghchj 的回复:] 如果connect超时了,你又不return,后面的send、recv的意义在哪?不返回给你超时你想它返回给你什么?
if(!ret) { closesocket( sockfd ); fprintf(stderr , "Cannot Connect the server!/n"); return; }[/quote] 那看看服务端吧
轻箬笠 2019-07-24
  • 打赏
  • 举报
回复
引用 1 楼 sdghchj 的回复:
如果connect超时了,你又不return,后面的send、recv的意义在哪?不返回给你超时你想它返回给你什么?

if(!ret)
{
closesocket( sockfd );
fprintf(stderr , "Cannot Connect the server!/n");
return;
}
sdghchj 2019-07-24
  • 打赏
  • 举报
回复
如果connect超时了,你又不return,后面的send、recv的意义在哪?不返回给你超时你想它返回给你什么?
轻箬笠 2019-07-24
  • 打赏
  • 举报
回复
目前看服务端应该没问题。
第一,并发量不高,100左右。
第二,同一时间,其他客户端是可以发送成功的。

所以有没有可能“connect非阻塞,send和recv是阻塞的”这种模式会在某些情况下有问题?抑或,缓冲区的内容被刷掉之类的?或者直接往缓冲区写入数据失败?再或者是其他什么原因?目前处于瞎猜阶段。

如果是其中某种原因,可否提供下测试用的例子?

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧