首页 > 代码库 > 《UNIX网络编程》之read_timeout实验
《UNIX网络编程》之read_timeout实验
最近在做项目,需要做一个服务器和客户端的基于TCP的套接口网络编程,由于服务器端返回数据并不是那么的及时,因此,需要在客户端做些延迟,然后才能去读取数据,实验测试结果如下。
首先,我们先来看一下我们封装好的一个读延时函数:
#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0)/** * read timeout - 读超时检测函数,不含读操作 * @fd: 文件描述符 * @wait_seconds: 等待超时秒数,如果为0标识不检测超时 * 成功(未超时)返回0, 失败返回-1, 超时返回-1并且errno = ETIMEOUT */int read_timeout(int fd, unsigned int wait_seconds){ int ret; if(wait_seconds > 0) { fd_set read_fdset; struct timeval timeout; FD_ZERO(&read_fdset); FD_SET(fd, &read_fdset); timeout.tv_sec = wait_seconds; timeout.tv_usec = 0; do { ret = select(fd + 1, &read_fdset, NULL, NULL, &timeout); }while(ret < 0 && errno == EINTR); if(ret == 0)//fail { //time out. ret = -1; errno = ETIMEDOUT; } else if(ret == 1)//success { ret = 0; } } return ret;}
下面,我们介绍如何使用该函数,伪代码如下:
int ret = read_timeout(sockfd, 15);
if(ret == 0)
{
readnum = read(sockfd, recvbuff, sizeof(recvbuff));
}
else if(ret == -1 && errno == ETIMEDOUT)
{
//time out dealing.
}
好,现在继续看我的服务器与客户端程序:
服务器
void str_echo(int sock){ ssize_t n; char buff[1024]; again: while( (n = read(sock, buff, sizeof(buff))) > 0) { fputs(buff, stdout); sleep(3);//for testing client read_timeout write(sock, buff, n); } if(n < 0 && errno == EINTR) { goto again; } else if(n < 0) { ERR_EXIT("read"); }}int main(){ int listenfd, connfd; pid_t childpid; socklen_t clilen; struct sockaddr_in servaddr, cliaddr; if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ERR_EXIT("socket"); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(5188); if((bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0) { ERR_EXIT("bind"); } if( (listen(listenfd, SOMAXCONN)) < 0) { ERR_EXIT("listen"); } for(;;) { clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen); if(connfd < 0) { ERR_EXIT("connect"); } if( (childpid = fork()) == 0) { //child close(listenfd); str_echo(connfd); exit(0); } else { //parent close(connfd); } }}
客户端
void str_cli(int sock){ char sendbuff[1024]; char recvbuff[1024]; memset(sendbuff, 0, sizeof(sendbuff)); memset(recvbuff, 0, sizeof(recvbuff)); int ret = -1; //ssize_t n; while(fgets(sendbuff, sizeof(sendbuff), stdin) != NULL) { write(sock, sendbuff, strlen(sendbuff)); ret = read_timeout(sock, 15); if(ret == 0) { read(sock, recvbuff, sizeof(recvbuff)); } else if(ret == -1 && errno == ETIMEDOUT) { ERR_EXIT("read_timeout"); } fputs(recvbuff, stdout); }}int main(int argc, char **argv){ int sockfd; struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servaddr.sin_port = htons(5188); sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) { ERR_EXIT("socket"); } if( (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0) { ERR_EXIT("connect"); } str_cli(sockfd); return 0;}
例子一:
服务器延时3s, 客户端read_timeout(socd, 5);结果为:成功
《UNIX网络编程》之read_timeout实验
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。