【网络编程】非阻塞connect详解
来源:互联网 发布:武汉光谷相关数据 编辑:程序博客网 时间:2024/05/19 00:54
一、为什么使用非阻塞connect
TCP连接的建立涉及一个在三路握手过程,阻塞的connect一直等到客户收到自己的SYN的ACK才返回,这需要至少一个RTT时间,RTT时间波动很大从几毫秒到几秒。而且在没有响应时,会等待数秒再次发送,(详见TCPv2第828页),总共75秒到几分钟的connect超时时间。为了缩短超时时间,将非阻塞connect与select配合使用
二、connect的处理细节
1、当服务器和客户端在同一个主机上时,connect会立刻建立;
2、建立成功select监测到描述符为可写(详见TCPv2第531页);
3、建立失败select检测到描述符为可读可写(详见TCPv2第530页);
4、当可写返回时,通过写成功与否来判断,网络建立成功或失败。
三、代码详解
int MyConnect(int fd, char *addr, int port, int timeout)
{struct sockaddr_in server_addr;
int ioFlags = 0;
int ret;
char temp_addr[IP_LEN];
//设置非阻塞读写,使connect成为非阻塞的
ioFlags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, ioFlags|O_NONBLOCK);
//设置服务器地址
memset(&server_addr, 0, sizeof(struct sockaddr_in));
memset(temp_addr, 0, IP_LEN);
strcpy(temp_addr,addr);
if (inet_aton(temp_addr, &server_addr.sin_addr) == 0)
{
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
return -1;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
//连接服务器
ret = connect(fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if( ret == 0 ) //连接成功,服务器与客户端立即建立连接
{
}
else
{
if( errno != EINPROGRESS ) //连接失败,EINPROGRESS代表正在进行三次握手
{
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
}
else //(errno==EINPROGRESS) //正在进行三次握手
{
fd_set rSet, wSet;
struct timeval to;
FD_ZERO(&rSet);
FD_SET(fd, &rSet);
wSet = rSet;
to.tv_sec = timeout;
to.tv_usec= 0;
ret = select(fd+1, &rSet, &wSet, NULL, &to);//监听网络
if(ret<0) //select返回错误,连接失败
{
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
}
else if(ret==0) //连接超时
{
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
return -1;
}
else
{
if( FD_ISSET(fd, &wSet) )
{
errno = 0;
char t = 0;
ret = send(fd, &t, 0, 0);
if( (ret==0)&&(errno==0) ) //连接成功
{
}
else
{
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
return -1;
}
}
else
{
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
return -1;
}
}
}
}
//再次设置非阻塞读写
fcntl(fd, F_SETFL, ioFlags);
return 0;
}
阅读全文
0 0
- 【网络编程】非阻塞connect详解
- 网络编程学习笔记(非阻塞connect)
- Linux网络编程 - 非阻塞connect
- linux网络编程-----非阻塞connect
- TCP网络编程--非阻塞accept和非阻塞connect
- TCP网络编程--非阻塞accept和非阻塞connect
- 非阻塞connect编程
- 在网络编程的时候使用非阻塞的connect
- UNIX网络编程——非阻塞connect
- UNIX网络编程--非阻塞connect的实现
- UNIX网络编程--非阻塞connect的实现
- 唯快不破:UNIX网络编程--非阻塞connect的实现
- 【Socket编程】非阻塞connect
- 唯快不破:TCP网络编程--非阻塞accept和非阻塞connect
- 编程:网络编程之linux 客户端 Socket 非阻塞connect编程(正文)
- Linux非阻塞网络connect (记录)
- linux 客户端 Socket 非阻塞connect编程
- linux 客户端 Socket 非阻塞connect编程
- 【NIO详解】Buffer源码剖析
- Android应用程序——四大组件之Activity
- latex
- 应用层读写I2C信息,可读写寄存器为8位或者16位的reg信息
- 加密、解密详解及CA的实现
- 【网络编程】非阻塞connect详解
- Python大文件解析的效率问题
- Android adb 常用命令
- Python 学习之namedtuple的使用
- 不使用+、-、*、/完成两个整数的相加
- 快速排序
- MFC之如何弹出模态窗口
- VSLAM分类
- HDU2093 考试排名(排序)