Unix网络编程之select版客户端实现
2016-09-19 19:37
316 查看
1.当客户端阻塞于某个输入操作时,服务器发送过来的终止连接的消息或者服务器崩溃的FIN,客户端将接受不到,而客户端以为服务器还在正常运行,一味的给服务器发消息。那么客户端将收到一个RST,但是客户端正忙于其他操作,忽略了这个RST,客户端继续调用read方法,如果read方法调用发生在RST到来之前,将返回一个0(EOF),否则返回一个ECONNRESET(对方复位连接错误),最终退出程序。
2.因此,我们可以用select 的i/o复用的方式重新编写我们的代码:
客户端改编之后的代码:
接下来是strcli函数的select 实现方法:
2.因此,我们可以用select 的i/o复用的方式重新编写我们的代码:
客户端改编之后的代码:
#include "unp.h" int main(int argc, char **argv){ int sockfd; struct sockaddr_in servaddr; if(argc != 2) err_quit("usage : tcpcli <IPaddress>"); sockfd = Socket(AF_INET,SOCK_STREAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); Inet_pton(AF_INET,argv[i],&servaddr.sin_addr); Connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); strcli(stdin,sockfd); exit(0); }
接下来是strcli函数的select 实现方法:
#include "unp.h" void str_cli(FILE *fp, int sockfd){ int maxfdp1,stdineof; //我们设置一个stdineof的标志位,为零代表它可以往sockfd里面写 fd_set rset; char buf[MAXLINE] int n; stdineof = 0; FD_ZERO(&rset); for(;;){ if(stdineof == 0) FD_SET(fileno(fp),&rset); //如果标志位为0 , 那么我们把输入流的描述符设置一下。 FD_SET(sockfd,&rset); //套接字的描述符是都应该设的,因为我们一般只是关闭客户端的写操作,对于服务器发送来的消息还是可以读到的。 maxfdp1 = max(fileno(fp),sockfd)+1; Select(maxfdp1,&rset,NULL,NULL,NULL); if(FD_ISSET(sockfd,&rset)){ //判断套接字是否可读,如果可读,读入到buf缓冲区里面。 if((n = Read(sockfd,buf,MAXLINE)) == 0){ if(stdineof == 1){ //如果我们正处在FIN-WAIT-1 状态下,我们就直接返回就行了,因为我们已经受到了来自服务器端的FIN。 return; }else err_quit("str_cli : server terminated"); } Write(fileno(stdout,buf,MAXLINE)); } if(FD_ISSET(fileno(stdin),&rset)){ //判断输入流里面是否可读,如果可读,把它读到buf缓冲区里面。 if((n = Read(fileno(stdin),buf,MAXLINE)) == 0){ stdineof = 1; //如果我们读到了来自服务器端的FIN,那么我们就直接将stdineof标志位设置成 1 Shutdown(sockfd,SHUT_WR); //然后我们向服务器发送ACK,并且还有我们的FIN。 FD_CLR(fileno(fp),&rset); //接下来我们一定要将rset里面注册的监听描述符移除掉,不让内核再去判断他是否可读 continue; } Writen(sockfd,buf,n); } } }
相关文章推荐
- Cocos2dx 链接HTTP网络服务器
- https://git.oschina.net/mkk/spring-logback/tree/master/src/main/webapp?dir=1&filepath=src%2Fmain%2Fwebapp&oid=0124d58e997222d18a2415dddbe6054911e67b68&sha=742f8b62bb4057609c40a1062134721317ccf78f
- hdu 5900 QSC and Master(区间dp 沈阳网络赛)
- http://www.tuicool.com/articles/Y7femm
- 第三方okhttp网络访问框架使用教程
- TCP三次握手及其背后的缺陷
- hdu 5898 odd-even number (数位dp 沈阳网络赛)
- Modbus协议分类
- iOS开发中AFNetworking中如何设置https请求(使用自建证书)
- Linux网络协议栈之数据包处理过程
- 网络状况判断
- hdu 5894 分位置(组合数学,沈阳网络赛)
- 轻量级HTTP服务器Nginx(Nginx性能优化技巧)
- iOS 网络编程大小端格式
- [Windows网络编程课设]南工程聊天室服务器源码
- HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛
- 以OKHttp为基础封装网络请求工具类
- httpURLConnection-网络请求的两种方式-get请求和post请求
- HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛
- HDU-5900 QSC and Master