[原创]C 语言select函数
参考链接:http://www.cnblogs.com/GameDeveloper/p/3406565.html
注意点: select() 只是执行一次的超时检测。重新进行select要重新设置“超时时间”以及“句柄”。
connect 非阻塞的例子:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <time.h> #include <fcntl.h> #include <errno.h> #include <string.h> int main(int argc, char** argv) { int sockfd,recvbytes,res,flags,error=-1,n; socklen_t len; fd_set rset,wset; struct timeval tval; struct sockaddr_in serv_addr; char*sendData="1234567890";//发送字符串 char buf[1024]="/0"; //接收buffer //创建socket描述符 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket create failed"); return 1; } serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(9999); serv_addr.sin_addr.s_addr=inet_addr("172.16.0.111"); bzero(&(serv_addr.sin_zero),8); flags=fcntl(sockfd,F_GETFL,0); fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);//设置为非阻塞 if( (res = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) )< 0) { if(errno != EINPROGRESS) { return 1; } } //如果server与client在同一主机上,有些环境socket设为非阻塞会返回 0 // if(0 == res) goto done; while(error!=0){ tval.tv_sec=0; tval.tv_usec=3000000; //要在while重新设置时间,否则超时不生效 FD_ZERO(&rset); //要在while重新添加句柄,否则检测不了变化 FD_SET(sockfd,&rset); wset=rset; printf("enter while\n"); res = select(sockfd+1, NULL, &wset, NULL,&tval) ; if( res == 0) { perror("connect time out\n"); // close(sockfd); // return 1; } else { if(res>0){ len=sizeof(error); getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); printf("error:%d\n", error); if(error) { fprintf(stderr, "Error in connection() %d - %s\n", error, strerror(error)); // return 1; } } } } if(res !=0) { printf("done\n"); if( (n = send(sockfd, sendData, strlen(sendData),0) ) ==-1 ) { perror("send error!"); close(sockfd); return 1; } if( ( n = select(sockfd+1,&rset,NULL, NULL,&tval)) <= 0 )//rset没有使用过,不用重新置为sockfd { perror("receive time out or connect error"); close(sockfd); return -1; } if((recvbytes=recv(sockfd, buf, 1024, 0)) ==-1) { perror("recv error!"); close(sockfd); return 1; } printf("receive num %d\n",recvbytes); printf("%s\n",buf); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?