select 优化socket回射服务器
来源:互联网 发布:中宣部知乎 编辑:程序博客网 时间:2024/06/04 22:46
注意:readset被每次需要重新set,所以用allset先保存下来,每次重新赋值给readset
server.c
#include <unistd.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/types.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <signal.h>#include <arpa/inet.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>/* int socket(int domain, int type, int protocol); *//* int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); //man 2 bind struct sockaddr { sa_family_t sa_family; char sa_data[14]; } //man 7 ip struct sockaddr_in { sa_family_t sin_family; // address family: AF_INET u_int16_t sin_port; // port in network byte order struct in_addr sin_addr; // internet address }; //Internet address. struct in_addr { u_int32_t s_addr; //address in network byte order }; *///int listen(int sockfd, int backlog);//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);/* On success, accept() returns a non-negative integer that is a descriptor for the accepted socket. On error, -1 is returned, and errno is set appropriately. */int main(){ int sockfd = 0; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("fun socket"); exit(0); } struct sockaddr_in srvaddr; srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(8001); srvaddr.sin_addr.s_addr = (INADDR_ANY); int on = 1; //bind socket error: Address already in use if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror("setsockopt"); return -1; } if (bind(sockfd, (struct sockaddr *) &srvaddr, sizeof(srvaddr)) < 0) { perror("fun bind"); return -1; } if (listen(sockfd, SOMAXCONN) < 0) { perror("fun listen"); return -1; } int i; int client[FD_SETSIZE]; int maxi = 0; memset(client,-1,FD_SETSIZE); fd_set read_set; fd_set all_set; FD_ZERO(&read_set); FD_ZERO(&all_set); int maxfd = sockfd; FD_SET(sockfd,&all_set); while(1) { read_set = all_set;//重新准备要被监听的文件描述符集合,这也是select的缺点之一 int nready = select(maxfd+1,&read_set,NULL,NULL,NULL); if(nready == -1) { if(errno == EINTR) continue; return -1; } else if(nready == 0) { continue;//timeout } if(FD_ISSET(sockfd,&read_set)) { struct sockaddr_in peer_addr; //The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; socklen_t peerlen = sizeof(peer_addr); int conn = accept(sockfd,(struct sockaddr*)&peer_addr,&peerlen); if(conn == -1) { perror("accept error"); return -1; } printf("perradd:%s\n perrport:%d\n", inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port)); for(i = 0; i < FD_SETSIZE; i++) { if(client[i] == -1) { client[i] = conn; if(i > maxi) maxi = i; break; } } FD_SET(conn,&all_set); if(conn > maxfd) maxfd = conn; if(--nready > 0) continue; } for(i = 0; i <= maxi; i++) { int conn = client[i]; if(conn == -1) continue; if(FD_ISSET(conn,&read_set)) { char recvbuf[1204]; memset(recvbuf,0x00,sizeof(recvbuf)); int nread = read(conn,recvbuf,sizeof(recvbuf)); if(nread == 0) { printf("peer has closed\n"); FD_CLR(conn,&all_set); client[i] = -1; close(conn); } fputs(recvbuf,stdout); write(conn,recvbuf,nread); memset(recvbuf,0x00,sizeof(recvbuf)); } } } return 0;}
#include <unistd.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/types.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <signal.h>#include <arpa/inet.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/select.h>#include <sys/time.h>#include <unistd.h>/* int socket(int domain, int type, int protocol); *//* int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); //man 2 bind struct sockaddr { sa_family_t sa_family; char sa_data[14]; } //man 7 ip struct sockaddr_in { sa_family_t sin_family; // address family: AF_INET u_int16_t sin_port; // port in network byte order struct in_addr sin_addr; // internet address }; //Internet address. struct in_addr { u_int32_t s_addr; //address in network byte order }; *///int listen(int sockfd, int backlog);//accept 接受一个新的连接 ,这个新的连接是一个主动套接字/* int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); On success, accept() returns a non-negative integer that is a descriptor for the accepted socket. On error, -1 is returned, and errno is set appropriately. int conn = 0; */int main(int argc,char *argv[]){ if(argc != 2) { printf("./client IPAddress\n"); return -1; } int sockfd = 0; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("fun socket\n"); exit(0); } struct sockaddr_in srvaddr; srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(8001); srvaddr.sin_addr.s_addr = inet_addr(argv[1]); //127.0.0.1 if (connect(sockfd, (struct sockaddr*) (&srvaddr), sizeof(srvaddr)) < 0) { perror("fun socket\n"); exit(0); } printf("connect success\n"); char revbuf[1024] = { 0 }; char sendbuf[1024] = { 0 }; /* while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) { //向服务写数据 write(sockfd, sendbuf, strlen(sendbuf)); //从服务器读数据 read(sockfd, revbuf, sizeof(revbuf)); // fputs(revbuf, stdout); //从服务器收到数据,打印屏幕 memset(revbuf, 0, sizeof(revbuf)); memset(sendbuf, 0, sizeof(sendbuf)); } */ fd_set read_set; FD_ZERO(&read_set); int stdin_fd = fileno(stdin); int maxfd = (sockfd > stdin_fd ? sockfd : stdin_fd); fd_set all_set; FD_ZERO(&all_set); FD_SET(stdin_fd,&all_set); FD_SET(sockfd,&all_set); while(1) { read_set = all_set; int ret = select(maxfd+1,&read_set,NULL,NULL,NULL); if(ret == -1) { perror("select error"); return -1; } else if(ret == 0) { printf("timeout\n"); return -1; } else if(ret == 1) { if(FD_ISSET(stdin_fd,&read_set)) { fgets(sendbuf,sizeof(sendbuf),stdin); write(sockfd, sendbuf, strlen(sendbuf)); memset(sendbuf, 0, sizeof(sendbuf)); printf("write sock\n"); } if(FD_ISSET(sockfd,&read_set)) { int nread = read(sockfd, revbuf, sizeof(revbuf)); if(nread == 0) { printf("peer closed\n"); break; } fputs(revbuf, stdout); memset(revbuf, 0, sizeof(revbuf)); printf("read sock\n"); } } } close(sockfd); return 0;}
0 0
- select 优化socket回射服务器
- select 实现的 socket服务器
- socket select模型服务器设计
- select() +socket 实现 socket服务器 -Linux
- socket 回射服务器
- 基于Select模型的Socket服务器
- socket 的select 服务器/客户机程序
- Socket学习之select最简版服务器
- select和poll回射服务器程序
- socket通信之五:select多路复用的客户/服务器模型
- Socket学习select服务器最简单的客户端
- Socket学习之select多路复用的客户/服务器模型
- socket select
- Socket Select
- Socket & Select
- Socket-Select
- Socket Select
- socket select
- ScrollView 嵌套 RecyclerView 高度自适应遇到的问题
- 数据库增删改命令 分类笔记
- linux中的动态、静态库
- Record Locks
- 传统IO socket
- select 优化socket回射服务器
- iOS10推送项目配置
- 监控线上服务器运行情况脚本
- unsigned类型需要注意的事项
- C++“准”标准库Boost学习指南(9):Boost.Bind
- combobox下拉框级联并且每一个框默认选择第一个值使用onLoadSuccess——easyUI
- reinforcement learning,增强学习:Policy Evaluation,Policy Iteration,Value Iteration,Dynamic Programming f
- 搭建Struts2开发环境
- “九头虫”病毒技术分析报告