socket阻塞与非阻塞读写
来源:互联网 发布:淘宝流量推广软件 编辑:程序博客网 时间:2024/05/22 16:19
网络协议一般都是由head和body构成。
socket在实际应用中有2种方式,阻塞和非阻塞。
使用setsockopt()可以在2种方式之间切换。
/**** 设置非阻塞模式(for Win32)* **/int nNonBlocking = 1;ioctlsocket(sockListen,FIONBIO,&nNonBlocking);
/**** 功能 - 阻塞模式读取指定字节协议内容* * 参数 - sockfd, 套接字句柄* - pBuffer, 接收缓冲区* - nBufferLen, 接收缓冲区大小* - nBytesToRead, 需要读取的大小** 返回值* true - 成功读取nBytesToRead个字节* false - 发生错误(SOCKET_ERROR), 连接关闭(0)***/bool ReadMessage(int sockfd , char * pBuffer , size_t nBufferLen , size_t nBytesToRead) { int nRead = 0, nFinished = 0; while (nFinished < nBytesToRead) { if (0 >= (nRead = recv(sockfd , pBuffer + nFinished , nBytesToRead - nFinished , 0))) break; nFinished += nRead; } if (nFinished == nBytesToRead) { return true; } return false; }
非阻塞模式:
先看一个辅助函数, 检测缓冲区是否就绪
/**** 功能 - 测试指定socket的数据是否可读* * 参数 - hSocket, 需要测试的socket句柄** 返回值* -1 SOCKET_ERROR* 0 BUSY* 1 READY**/int IsRecvBufReady(SOCKET hSocket){fd_set sockSet; FD_ZERO(&sockSet);FD_SET(hSocket,&sockSet);struct timeval interval;interval.tv_sec = 0;interval.tv_usec = 0;int nPending = select(0 // 忽略 , sockSet // 可读, NULL // 可写, NULL // 错误, &interval); // 超时return nPending;}/**** 功能 - 读取指定字节** 参数 - hSocket, socket句柄* - pBuffer, 接收缓冲区* - nBufferLen, 缓冲区大小* - nBytesToRead, 需要读取的指定大小** 返回值* -1 发生错误* 1 成功* 0 读取的字节数小于nBytesToRead, 下次读取**/int ReadMessage(SOCKET hSocket , char * pBuffer , size_t nBufferLen , size_t nBytesToRead){ int nStatus = -1; size_t nRead = 0, nFinished = 0; while (0 > (nStatus = IsRecvBufReady(hSocket))) { if (0 >= (nRead = recv(hSocket , pBuffer + nFinished , nBytesToRead - nFinished , 0))) return -1; nFinished += nRead; if (nFinished == nBytesToRead) return 1; } return nStatus;}
常用的socket属性设置setsockopt
/**** 开启NOLINGER配置* 立即关闭socket* 不等待缓冲区的数据发送出去* 避免出现大量的FIN_WAIT_2状态的socket占用资源* * 备注: tcp连接关闭的过程* * Me Peer* 1, close() -> [FIN] -> * 2, FIN_WAIT_1 CLOSE_WAIT* 3, <- [ACK] <- * 4, FIN_WAIT_2 * 5, <- [FIN] <- close()* 6, TIME_WAIT LAST_ACK* 7, -> [ACK] -> * 8, CLOSED CLOSED**/struct linger noLinger;noLinger.l_onoff = 1;noLinger.l_linger = 0;setsockopt(hSocket, SOL_SOCKET, SO_LINGER, (const char *)&noLinger, sizeof(noLinger));/**** No-Nagle* 不需要在缓冲区中整合小包碎片* 立刻发送* 不用凑齐链路层的一个帧大小* **/int NoNagleFlag = 1;setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&NoNagleFlag, sizeof(NoNagleFlag));/**** 设置超时* 注意: linux和win的参数不一样***/int nTimeout = 6000;setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&nTimeout,sizeof(nTimeout))
源代码;
http://hi.csdn.net/attachment/201112/20/0_1324361094v7Tx.gif
- socket阻塞与非阻塞读写
- socket阻塞与非阻塞
- 阻塞非阻塞socket
- socket阻塞,非阻塞
- socket的阻塞与非阻塞模式
- socket connect 阻塞与非阻塞
- socket编程中的阻塞与非阻塞
- socket阻塞与非阻塞区别
- SOCKET的阻塞与非阻塞
- socket中的阻塞与非阻塞
- socket阻塞与非阻塞 windows下
- Socket同步、异步与阻塞、非阻塞
- Socket 阻塞与非阻塞模式
- socket的阻塞与非阻塞
- socket connect 阻塞与非阻塞 .
- socket阻塞与非阻塞的区别
- socket阻塞与非阻塞模式区别
- Socket 阻塞与非阻塞模式
- 用SimpleAdapter实现ListView
- Java咖啡馆——叹咖啡
- 起点
- 编程艺术第二十三~四章&十一续:杨氏矩阵查找,倒排索引关键词Hash编码
- windows远程桌面连接fedora14
- socket阻塞与非阻塞读写
- 贝佐斯:亚马逊是科技界唯一一家低利润公司
- 一号通网络浏览平台畅想
- [转]23种设计模式的通俗理解
- 转:EOF是什么
- install parallels workstation 6 extreme on Fedora 15
- OpenCV的深度图
- include与require的区别
- 判断Object对象类型的关键字