select与shutdown
来源:互联网 发布:阿里云centos7 lamp 编辑:程序博客网 时间:2024/05/22 03:04
相关网络编程函数:http://blog.csdn.net/somehow1002/article/details/72648743
我们已经实现了一个基本的并发回射服务器程序,但是依然存在问题。
如果当客户端阻塞于标准输入时,服务器进程可能因为各种原因结束了。服务器TCP虽然正确的给客户端TCP发送了一个FIN,但是客户端进程正阻塞在标准输入上,可能很长时间之后才能接受到这个信息。针对这个问题,可以使用IO复用方法来解决。
客户端程序既要处理标准输入,又要处理套结字上到达的信息。对于多种IO,使用select函数解决这个问题。
客户端要处理的各种信息如下:
对于客户端的套结字上的三个条件处理如下:
1.如果对端TCP发送数据,那么该套结字变为可读,并且返回一个大于0的值
2.如果对端TCP发送了一个FIN(对端进程终止),那么该套结字变为可读,并且read返回0(EOF)
3.如果对端TCP发送了一个RST(对端主机崩溃并重新启动),那么该套结字变为可读,并且read返回-1,而errno中含有确切的错误码。
依此我们修订str_cli函数如下
void str_cli(FILE *fp,int sockfd){ int maxfdp1; fdset rset; char sendline[MAXLINE],recvline[MAXLINE]; FD_ZERO(&rset); for(;;){ FD_SET(fileno(fp),&rset); FD_SET(sockfd,$rset); maxfdp1=max(fileno(fp),sockfd)+1; select(maxfdp1,&rset,NULL,NULL,NULL); if(FD_ISSET(sockfd,&rset)){ if(readline(sockfd,recvline,MAXLINE)==0){ printf("str_cli:server terminated prematurely"); exit(-1); } fputs(recvline,stdout); } if(FD_ISSET(fileno(fp),&rset)){ if(fgets(sendline,MAXLINE,fp)==NULL) return ; Writen(sockfd,sendline,strlen(sendline)); } }}
问题
设想一种情况,客户端要传输大量的消息,这些消息正在传输中。而我们写完所有请求之后,并不能立即关闭连接,因为管道中还有其他的请求和应答。问题的起因在于我们对标准输入中EOF的处理:str_cli函数就此返回到main函数,而main函数随后终止。然而在这种批量方式下,标准输入中的EOF并不意味这完成了从套结字的读入。总结起来就是:客户端输入的EOF并不意味这客户端处理的完成(可能还要从套接字读入,然而客户端已经结束了)。
要解决这个问题,我们将套结字的读写两个方向的数据传输分开处理,使用shutdown函数,而不是原先的close函数。
使用select,shutdown正确处理EOF的str_cli函数
void str_cli(FILE *fp,int sockfd){ int maxfdp1,stdineof; fd_set rset; char buf[MAXLINE]; int n; stdineof=0; FD_ZERO(&rset); for(;;){ if(stdineof==0) FD_SET(fileno(fp),&rset); FD_SET(sockfd,&rset); maxfdp1=max(fileno(fp),sockfd)+1; select(maxfdp1,&rset,NULL,NULL,NULL); if(FD_ISSET(sockfd,&rset)){ if((n=read(sockfd,buf,MAXLINE))==0){ if(stdineof==1) return ; else { printf("str_cli:server terminated prematurely\n"); exit(-1); } } write(fileno(stdout),buf,n); } if(FD_ISSET(fileno(fp),&rset)){ if((n=read(fileno(fp),buf,MAXLINE))==0){ stdineof=1; shutdown(sockfd,SHUT_WR); FD_CLR(fileno(fp),&rset); continue; } Writen(sockfd,buf,n); } }}
阅读全文
0 0
- select与shutdown
- 使用select和shutdown
- shutdown与startup命令
- ThreadPool shutdown 与shutdownNow
- shutdown与poweroff
- shutdown与shutdownNow
- 【linux】close与shutdown
- close与shutdown
- 《unix网络编程》(13)select、shutdown函数
- 利用select和shutdown的str_cli函数
- close与shutdown的区别
- startup与shutdown参数说明
- SO_LINGER 选项 与 shutdown 函数
- shutdown 与 close 的区别
- oracle的shutdown与startup
- shutdown
- Shutdown
- Shutdown
- 面试遇到的一些基础细节问题
- 深度学习中Dropout策略
- 对一个数进行若干变换直至变成个位数
- 用FileZilla搭建FTP服务器及相关问题
- 与倒数第N个节点相关的题目
- select与shutdown
- 跨站请求伪造CSRF
- 富文本编辑器 CKeditor 的使用
- iOS开发遍历集合(NSArray,NSDictionary、NSSet)方法总结
- 从extends和super浅谈java泛型
- selenium webdriver——JavaScript警告窗处理
- 互联网架构(7):Socket网络通信编程--BIO/NIO/AIO
- paper阅读:流形上的预积分理论
- JSON.parse()和JSON.stringify()