用select实现TCP回射程序(服务器及客户端)
2017-11-29 16:51
369 查看
该程序系参考《UNP》来编写的,主要用来练习select及shutdown函数的使用。
服务器代码
客户端代码
服务器代码
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/select.h> #include <string.h> #include <strings.h> #include <errno.h> #define PORT 8888 #define BACKLOG 100 #define MAXLINE 1024 int main() { int listenfd, connfd, sockfd; int client[FD_SETSIZE]; int i, n; struct sockaddr_in servaddr, cliaddr; socklen_t clilen; fd_set rset, allset; int maxfd, maxcli; int nready; char buf[MAXLINE]; //创建监听套接字 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket error\n"); exit(1); } //写入套接字地址 bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); //绑定地址 if ((n = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0) { printf("bind error\n"); exit(1); } //监听 if ((n = listen(listenfd, BACKLOG)) < 0) { printf("listen error\n"); exit(1); } for (i = 0; i < FD_SETSIZE; i++) client[i] = -1; maxfd = listenfd; maxcli = -1; FD_ZERO(&allset); FD_SET(listenfd, &allset); for (;;) { rset = allset; if ((nready = select(maxfd + 1, &rset, NULL, NULL, NULL)) < 0) { printf("select error\n"); printf("%s\n", strerror(errno)); exit(1); } if (FD_ISSET(listenfd, &rset)) { //接受新连接 if ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0) { printf("accept error\n"); exit(1); } printf("accept: %d\n", connfd); //更新连接表 for (i = 0; i < FD_SETSIZE; i++) if (client[i] < 0) { client[i] = connfd; break; } FD_SET(connfd, &allset); //更新描述符集 if (connfd > maxfd) maxfd = connfd; //更新最大文件描述符 if (i > maxcli) maxcli = i; //更新最大连接表索引 if (--nready <= 0) continue; } for (i = 0; i <= maxcli; i++) { if ((sockfd = client[i]) < 0) continue; if (FD_ISSET(sockfd, &rset)) { if ((n = read(sockfd, buf, MAXLINE)) == 0) { if (close(sockfd) < 0) { printf("close error\n"); exit(1); } printf("close: %d\n", sockfd); FD_CLR(sockfd, &allset); client[i] = -1; } else { if (n < 0) { printf("read error\n"); exit(0); } if (n > 0) { if (write(sockfd, buf, n) < 0) { printf("write error\n"); exit(1); } } } if (--nready <= 0) break; } } } }
客户端代码
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/select.h> #include <string.h> #include <strings.h> #define PORT 8888 #define MAXLINE 1024 int main(int argc, char* argv[]) { int sockfd; int n; struct sockaddr_in servaddr; char buf[MAXLINE]; fd_set rset; int maxfd; int stdineof; if(argc != 2){ printf("invalid usage!\n"); exit(1); } if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("socket error!\n"); exit(1); } servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); if((n = inet_pton(AF_INET, argv[1], &servaddr.sin_addr)) < 0){ printf("pton error\n"); exit(1); } else if(n == 0){ printf("invalid ip\n"); exit(1); } if((n = connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0){ printf("connect error\n"); exit(1); } maxfd = sockfd; FD_ZERO(&rset); stdineof = 0; for(;;){ if(stdineof == 0) FD_SET(0, &rset); FD_SET(sockfd, &rset); if((n = select(maxfd+1, &rset, NULL, NULL, NULL)) < 0){ printf("select error\n"); exit(1); } if(FD_ISSET(0, &rset)){ if((n = read(0, buf, MAXLINE)) == 0){ stdineof = 1; if(shutdown(sockfd, SHUT_WR) < 0){ printf("shutdown error\n"); exit(1); } FD_CLR(0, &rset); continue; } else if(n < 0){ printf("stdin read error\n"); exit(1); } if((n = write(sockfd, buf, n)) < 0){ printf("socket write error\n"); exit(1); } } if(FD_ISSET(sockfd, &rset)){ if((n = read(sockfd, buf, MAXLINE)) == 0){ if(stdineof == 1) break; else{ printf("server terminated\n"); exit(1); } } else if(n < 0){ printf("socket read error\n"); exit(1); } if((n = write(1, buf, n)) < 0){ printf("stdout write error\n"); exit(1); } } } return 0; }
相关文章推荐
- Java学习笔记(一)------服务器&客户端一对一通信小程序实现(TCP)
- Select I/O模型来实现一个并发处理多个客户端的TCP服务器 <转>
- 使用Select I/O模型来实现一个并发处理多个客户端的TCP服务器
- Select I/O模型来实现一个并发处理多个客户端的TCP服务器
- Linux TCP server系列(2)-简单优化服务器和客户端程序
- Linux下的单进程多用户TCP服务器,采用select方法实现。
- 从简单到复杂实现TCP客户端服务器通信
- Android Socket编程基于TCP实现客户端与服务器简易通信
- Python网络编程 3.1 由简单的TCP服务器、客户端程序分析相关方法
- TCP/UDP client/server library for Java, 最好的java语言tcp udp 服务器客户端实现库
- select实现tcp并发服务器的基本框架流程
- C# 网络编程之Tcp实现客户端和服务器聊天
- 基于select模型的tcp服务器------一个服务器如何与多个客户端进行通信?
- Linux基于TCP/IP简单的客户端、服务器通信程序实例
- Qt中利用TCP实现多个客户端之间相互发送消息系以及服务器的群发信息
- Linux基于TCP/IP简单的客户端、服务器通信程序实例
- Java基于TCP实现服务器和多客户端之间的通信
- 由 TIdTCPServer 提供客户端安装程序 WEB 下载的实现方法
- Windows下TCP聊天服务器与客户端雏形的实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现