Linux下connect函数 阻塞 与 非阻塞 问题
一、概述
linux系统下,connect函数是阻塞的,阻塞时间的长度与系统相关。而如果把套接字设置成非阻塞,调用connect函数时会报错Operation now in progress
,且errno被设置为EINPROGRESS
。下面将分析非阻塞时调用connect报错的原因,以及提供两个方法解决connet函数阻塞太久的问题。
二、connect函数报Operation now in progress
的原因
三、解决connet函数阻塞太久的问题
三次握手的过程就决定了connect函数是需要阻塞一段时间的,而我们是向避免它阻塞太久了,影响程序执行。下面提供2个可行的方法,仅供参考。
3.1 设置成非阻塞,且使用select等到连接的建立
// 接服务器并返回套接字,timeoutMs 毫秒
int tcpClientConnect(unsigned int u32SerIp, unsigned short port, int timeoutMs)
{// 1、创建tcp套接字int sockFd = -1;if ((sockFd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { printf("[%s %d] socket failed\n",__FILE__,__LINE__); return -1;} // 2、socket 设置非阻塞int flags = fcntl(sockFd,F_GETFL,0);if(-1 == fcntl(sockFd,F_SETFL,flags|O_NONBLOCK)){printf("Set socket unblock failed!");}// 3、准备服务器地址信息、连接struct sockaddr_in server_addr;; server_addr.sin_family=PF_INET; server_addr.sin_port=htons(port); server_addr.sin_addr.s_addr = u32SerIp; bzero(&(server_addr.sin_zero), 0); if (connect(sockFd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0){if(errno != EINPROGRESS){printf("[%s %d] Connect fail!\n",__FILE__,__LINE__);close(sockFd);return -1;}}// 4、select等待fd_set rset,wset;FD_ZERO(&rset);FD_SET(sockFd,&rset);wset = rset;struct timeval tv;tv.tv_sec = timeoutMs/1000;tv.tv_usec = (timeoutMs%1000)*1000;if(select(sockFd+1, &rset, &wset, NULL, &tv)==0){printf("[%s %d] select fail!\n",__FILE__,__LINE__);close(sockFd);return -1; }if(FD_ISSET(sockFd,&rset) || FD_ISSET(sockFd,&wset)){int error;socklen_t len = sizeof(error);if(getsockopt(sockFd, SOL_SOCKET, SO_ERROR, &error, &len)<0)return -1; }printf("[%s %d] Connect pass! %d\n",__FILE__,__LINE__,sockFd);return sockFd;
}
3.2 使用套接字选项设置发送超时
// timeoutMs 毫秒
int tcpClientConnect(uint32_t u32SerIp, uint16_t port, int timeoutMs)//连接服务器并放回套接字 2022-06-23 20:02:34
{// 1、创建tcp套接字int sockFd = -1;if ((sockFd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { printf("[%s %d] socket failed\n",__FILE__,__LINE__); return -2;} // 2、设置 sockFd 超时时间*/if(timeoutMs > 0){struct timeval tv;tv.tv_sec = timeoutMs/1000;tv.tv_usec = (timeoutMs%1000)*1000;setsockopt(sockFd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));}// 3、准备服务器地址信息、连接struct sockaddr_in server_addr;; server_addr.sin_family=PF_INET; server_addr.sin_port=htons(port); server_addr.sin_addr.s_addr = u32SerIp; bzero(&(server_addr.sin_zero), 0); if (connect(sockFd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0){printf("[%s %d] Connect fail!\n",__FILE__,__LINE__);close(sockFd);return -1;}printf("[%s %d] Connect pass! %d\n",__FILE__,__LINE__,sockFd);return sockFd;
}
(650条消息) Linux下connect函数 阻塞 与 非阻塞 问题_wkd_007的博客-CSDN博客_connect linux
Linux下connect函数 阻塞 与 非阻塞 问题相关推荐
- linux函数阻塞,Linux下connect()函数阻塞与非阻塞
各位好,今天遇到一个奇怪的问题.在写socket客户端的程序时,发现connect()函数有时阻塞,有时非阻塞.且大部分时间是非阻塞的.下面是代码: socket_list[i].socket = s ...
- linux非阻塞输入函数,Linux fcntl函数设置阻塞与非阻塞
转自http://www.cnblogs.com/xuyh/p/3273082.html 用命令F_GETFL和F_SETFL设置文件标志,比如阻塞与非阻塞 F_SETFL 设置给arg描述符 ...
- connect函数在阻塞和非阻塞模式下的行为
connect函数在阻塞和非阻塞模式下的行为 当socket使用阻塞模式时,connect函数会阻塞到有明确结果才会返回,如果网络环境较差,可能要等一会,影响体验, 为了解决这个问题,我们使用异步co ...
- socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)
socket的阻塞模式和非阻塞模式 无论是Windows还是Linux,默认创建socket都是阻塞模式的 在Linux中,可以再创建socket是直接将它设置为非阻塞模式 int socket (i ...
- linux函数的阻塞与非阻塞IO及错误处理
linux函数的阻塞与非阻塞IO及错误处理 1.阻塞是指进程等待某一个事件的发生而处于等待状态不往下执行,如果等待的事件发生了则会继续执行该进程.调用系统阻塞函数可能会导致进程阻塞进入睡眠状态. 2. ...
- linux下recv 、send阻塞、非阻塞区别和用法
非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明: 基本概念: 阻塞IO:: socket 的阻塞模 ...
- linux下的阻塞和非阻塞
读常规文件是不会阻塞的,不管读多少字节,read 一定会在有限的时间内返回.从终 端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用 read 读终端设备就会 阻塞,如果网络 ...
- linux下阻塞的系统调用,Linux下文件的阻塞与非阻塞对部分系统调用的影响
1.基本概念 所谓的阻塞,即内核在对文件操作I/O系统调用时,如果条件不满足(可能需要产生I/O),则内核会将该进程挂起.非阻塞则是发现条件不满足就会立即返回.此外需要注意的是非阻塞并不是轮询,不然就 ...
- linux fcntl 设置阻塞,Linux fcntl函数设置阻塞与非阻塞
转自http://www.cnblogs.com/xuyh/p/3273082.html 用命令F_GETFL和F_SETFL设置文件标志,比如阻塞与非阻塞 F_SETFL 设置给arg描述符 ...
最新文章
- 数据库相关(JDBC,存储过程,以及大文本数据处理,mvc设计模式)
- Jenkins Pipeline高级用法-ShareLibrary
- ORACLE一致读与ORA-01555
- 2014 ACM/ICPC Asia Regional Xi'an Online
- Oracle NID工具修改数据库DBID和数据库名称
- error C2265: 'Unknown' : reference to a zero-sized array is illegal
- Diameter协议学习笔记一(协议介绍)
- 新中大财务软件V5.08安装
- 苹果手机怎样软件签名?
- 【机器学习】如何使用随机网格搜索,以缩短网格搜索速度?
- [RE]如何调整堆栈平衡
- 结构体定义 typedef struct LNode 用法说明
- CausalImpact
- android自定义系统屏保Dream
- unity中计算三角形的外接圆
- 获奖团队访谈录|“AI+无线通信赛道”二等奖团队
- 小米布局金融5年:新网银行遭银保监通报侵权,小米数科被列入经营异常
- 为什么理想电流源的等效内阻是无限大
- SLife 共享生活:去中心化的线下商业交易系统
- 毕业一年,程序猿工作一年总结,有收获,有失去,有遗憾,但仍一往无前