1、 long tv_usec; ;你可以这样赋值: timeout.tv_sec=1; timeout.tv_uec=0;表示检测在1秒钟内是否有句柄状态发生变化。如果有句柄发生变化,就可以用FD_ISSET检测各个句柄,比如: FD_ISSET (fd1, &/检测是否fd1变成可读的了 FD_ISSET (fd2, &/检测是否fd2变成可写的了示意程序代码如下: fd1 = socket();/创建一个socket fd2 = socket(); while(1) ret = select(fd1>fd2?(fd1+1):(fd2+1), &readfds, &writefds, N
2、ULL, &timeout); if(ret < 0) printf(系统错误,select出错,错误代码:%d, 错误信息:%s, errno, strerror(errno); else if(ret = 0) printf(select超时返回,没有任何句柄状态发生变化!); /有句柄状态发生了变化 if(FD_ISSET(fd1, &readfds) fd1有数据可读; fd1里的数据被读出来; if(FD_ISSET(fd2, &writefds) fd2可写; fd2里发送数据给对方; 经常用到的几个自定义函数:1、开启监听的函数intOpenSCPServer(int po
3、rt, int total, int sendbuflen, int recvbuflen, int blockORnot, int reuseORnot) int sockfd = 0, ret = 0, opt = 0, flags=1; struct sockaddr_in laddr; ret = sockfd = socket(PF_INET, SOCK_STREAM, 0); 0) sprintf(errorMessage, OpenTCPServer socket() error! return:%d, errno=%d, errortext:%s %s, ret, errno,
4、 strerror(errno), GetCurrentTime(0, 0); return -1; ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseORnot, sizeof(int);OpenTCPServer setsockopt() reuse error! return -2; ret = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &recvbuflen, sizeof(int); if ( ret &OpenTCPServer setsockopt() recvbuf err
5、or! return -3; ret = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuflen, sizeof(int); if (ret &OpenTCPServer setsockopt() sendbuf error! return -4; ioctl(sockfd,FIONBIO,&blockORnot); laddr.sin_family = PF_INET; laddr.sin_port = htons(port); laddr.sin_addr.s_addr = INADDR_ANY; bzero(&(laddr.sin_ze
6、ro), 8); ret = bind(sockfd, (struct sockaddr *)&laddr, sizeof(struct sockaddr);OpenTCPServer bind() error! close(sockfd); return -5; ret = listen(sockfd, total);OpenTCPServer listen() error! return -6;OpenTCPServer opened on port.%d(%d) OK, socket(%d), buf(%d:%d)!, port, total, sockfd, sendbuflen, r
7、ecvbuflen, GetCurrentTime(0, 0); return sockfd;2、连接服务器的函数intConnectSCPServer(char * serverip, int serverport, int blockORnot) int serversock = 0, ret = 0; unsigned long addr; struct sockaddr_in sin; struct hostent *he; if(he=gethostbyname(serverip)= 0) ConnectSCPServer IP address error!-1 %s, server
8、ip, GetCurrentTime(0, 0); serversock = socket(PF_INET, SOCK_STREAM, 0); if(serversock = -1) ConnectSCPServer socket() error!-2, errno=%d, errortext:, errno, strerror(errno), GetCurrentTime(0, 0); ioctl(serversock, FIONBIO, & /block or not memset(char*)&sin, 0, sizeof(struct sockaddr_in); sin.sin_fam
9、ily = PF_INET; sin.sin_port = htons(serverport); sin.sin_addr = *(struct in_addr *)he-&h_addr); ret = connect(serversock, (struct sockaddr *)&sin, sizeof(sin); if(ret = -1) ConnectSCPServer connect() error!-3, errno=%d, errortext: close(serversock); return serversock;3、发送数据函数SendintSend(int sock, ch
10、ar * buf, size_t size, int flag, int timeout) int i = 0, ret = 0, intretry = 0; struct tim tival; fd_set writefds; int maxfds = 0; tival.tv_sec = timeout; tival.tv_usec = 0; FD_ZERO(& if(sock & FD_SET(sock, & maxfds=(sock & maxfds)?sock:maxfds); else Send socket:%d error!-2 %s, sock, GetCurrentTime(
11、0, 0); ret = select(maxfds + 1, NULL, &tival);= 0) 0) sprintf(errorMessage, %d select() error!, sock, ret, errno, strerror(errno), GetCurrentTime(0, 0); else sprintf(errorMessage, %d select timeout(%d)!, sock, timeout, GetCurrentTime(0, 0); close(sock); if(!(FD_ISSET(sock, &writefds) %d not in write
12、fds! while(i & size) ret = send(sock, buf + i, size - i, flag);%d send() error! if (EINTR = errno) if(intretry & 10) intretry+;continue;EINTR 10 times! else i += ret;%d send() OK! %d/%d bytes sent!, sock, i, size, GetCurrentTime(0, 0); return i;4、接收数据函数RecvintRecv(int sock, char * buf, size_t size,
13、int flag, int timeout) int i = 0, ret = 0, intretry = 0; fd_set readfds;Recv socket: ret = select(maxfds + 1, &readfds, NULL, NULL, &readfds) %d not in readfds! ret = recv(sock, buf + i, size - i, flag);= 0)%d recv() error! if(errno = EINTR) EINTR 10 times!%d recv() OK! %d/%d bytes received!最后需要说明的是:我这里讲到的源程序并不能实际地作为一个产品程序来用,实际情况下可能会有其它许多工作要做,比如可能要建立共享队列来存放 socket里读到的消息,也可能把发送消息先进行排队然后再调用Send函数。还有,如果不是全数字,在发送前一定要htonl转换为网络字节序,同理 接收到后一定要先ntohl由网络字节序转换为主机字节序,否则对方发送过来的0x00000001在你这里可能是0x00010000,因为高低位顺序 不同。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1