echo_server服务器多线程版本
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <memory.h> #include <signal.h> #include <string.h> #include <errno.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/wait.h> #include <sys/select.h> #include <poll.h> #include <pthread.h> int sockfd; void sign_handler(int signo) { pid_t pid; int stat; if(signo==SIGINT) { printf("echo server close\n"); close(sockfd); exit(1); } if(signo==SIGCHLD){ printf("client close\n"); wait(0); } return; } void out_fd(int fd) { struct sockaddr_in arr; socklen_t len=sizeof(arr); if(getpeername(fd,(struct sockaddr*)&arr,&len)<0){ perror("getpeername fail\n"); exit(1); } char ip[16]; memset(&ip,0,sizeof(ip)); inet_ntop(AF_INET,&arr.sin_addr.s_addr,ip,sizeof(ip)); printf("%s connected\n",ip); } void server_do(int fd) { char buffer[BUFSIZ]; while(1){ printf("ready to read\n"); memset(buffer,0,sizeof(buffer)); ssize_t size; if((size=read(fd,buffer,sizeof(buffer)))<0){ perror("server child read fail\n"); break; }else if(size==0){ break; }else{ printf("number of received bytes=%ld\n",size); buffer[size-1]='\0'; printf("%s\n",buffer); if(write(fd,buffer,size)<0){ if(errno==EPIPE){ break; } perror("server child write fail\n"); } } } } void *doit(void *arg) { int fd=*((int *)arg); server_do(fd); close(fd); return (void*)0; } int main(int argc,char *argv[]) { if(argc<2) { printf("usage:%s <port>",argv[0]); exit(1); } //注册信号 if(signal(SIGINT,sign_handler)==SIG_ERR){ perror("signal sigint error\n"); exit(1); } if(signal(SIGCHLD,sign_handler)==SIG_ERR){ perror("signal sigint error\n"); exit(1); } /*create socket*/ sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd<0){ perror("socket create fail\n"); exit(1); } /*bind socket*/ struct sockaddr_in serveraddr; serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(atoi(argv[1])); serveraddr.sin_addr.s_addr=INADDR_ANY; if(bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0){ perror("socket bind fail\n"); exit(1); } if(listen(sockfd,10)<0){ perror("socket listen fail\n"); exit(1); } //设置线程的分离属性 pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); int *iptr; while(1){ iptr=malloc(sizeof(int)); if((*iptr=accept(sockfd,NULL,NULL))>0){ out_fd(*iptr); } pthread_t th; int err; if((err=pthread_create(&th,&attr,doit,iptr))!=0){ perror("pthread create fail\n"); } pthread_attr_destroy(&attr); } return 0; }
echo_client客户端多线程版本
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <memory.h> #include <signal.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> int sockfd; void doit(void *arg) { char buffer[BUFSIZ]; ssize_t size; while((size=read(STDIN_FILENO,buffer,sizeof(buffer)))>0){ buffer[size-1]='\0'; write(sockfd,buffer,size); } shutdown(sockfd,SHUT_WR); } void cli_do(int sockfd) { char buffer[BUFSIZ]; pthread_t th; ssize_t size; pthread_create(&th,NULL,doit,NULL); while((size=read(sockfd,buffer,sizeof(buffer)))>0){ buffer[size-1]='\0'; write(STDOUT_FILENO,buffer,size); } } int main(int argc,char *argv[]) { if(argc<3){ printf("usage:%s <ip><port>",argv[0]); exit(1); } /*create socket*/ sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd<0){ perror("socket create fail\n"); } struct sockaddr_in serveraddr; serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(atoi(argv[2])); inet_pton(AF_INET,argv[1],&serveraddr.sin_addr.s_addr); if(connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0){ perror("server connect fail\n"); exit(1); } cli_do(sockfd); close(sockfd); return 0; }