点对点 客户端-服务器 聊天程序
服务器,客户端都是父进程、子进程分别负责发送、接收字符串。
另外使用了信号函数来发送和接收处理信号,比如当子进程结束时,传递一个信号给父进程,然后父进程会执行信号处理函数。
服务器端:
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<sys/types.h> 4 #include<sys/socket.h> 5 #include<errno.h> 6 #include<netinet/in.h> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<signal.h> 10 11 void handler(int sig)//这是信号处理函数 12 { 13 printf("recv a sig:%d",sig); 14 exit(EXIT_SUCCESS); 15 } 16 17 int main() 18 { 19 int sockfd=socket(AF_INET,SOCK_STREAM,0); 20 if(sockfd<0) perror("socket!!!!"); 21 22 int on=1; 23 int result=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));//启用套接字选项,必须在bind之前完成 24 if(result<0) perror("setsockopt"); 25 26 struct sockaddr_in server_addr; 27 memset(&server_addr,0,sizeof(server_addr)); 28 server_addr.sin_family=AF_INET; 29 server_addr.sin_port=htons(888); 30 server_addr.sin_addr.s_addr=htonl(INADDR_ANY); 31 32 33 int res=bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr)); 34 if(res<0)perror("bind!!!"); 35 36 res=listen(sockfd,50); 37 if(res<0) perror("listen!!"); 38 39 int conn_fd; 40 struct sockaddr_in peeraddr; 41 int addr_len=sizeof(peeraddr); 42 pid_t pid; 43 44 conn_fd=accept(sockfd,(struct sockaddr*)&peeraddr,&addr_len); 45 if(conn_fd<0)perror("accept!!"); 46 printf(" the ip of client:%s,the port of client:%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));//打印对等方的ip与端口 47 48 //signal(SIGUSR1,handler); 49 pid=fork(); 50 if(pid<0) 51 perror("fork failed"); 52 else if(pid==0) 53 { //子进程 54 char recvbuf[1024]={0}; 55 while(1) 56 { 57 memset(recvbuf,0,sizeof(recvbuf)); 58 int resu; 59 resu=read(conn_fd,recvbuf,sizeof(recvbuf)); 60 if(resu<0)perror("read"); 61 else if(resu==0) 62 { 63 printf("peer closed!!!!"); 64 //exit(EXIT_SUCCESS); 65 kill(getppid(),SIGUSR1);//发送一个信号给父进程 66 break; 67 } 68 fputs(recvbuf,stdout); 69 } 70 //close(conn_fd); 71 //close(sockfd); 72 exit(EXIT_SUCCESS); 73 } 74 else //父进程 75 { 76 signal(SIGUSR1,handler);//安装信号接收函数 77 char sendbuf[1024]={0}; 78 while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL) 79 { 80 write(conn_fd,sendbuf,strlen(sendbuf)); 81 memset(sendbuf,0,sizeof(sendbuf)); 82 } 83 //close(conn_fd); 84 //close(sockfd); 85 exit(EXIT_SUCCESS); 86 } 87 return 0; 88 }
客户端:
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<sys/types.h> 4 #include<sys/socket.h> 5 #include<errno.h> 6 #include<netinet/in.h> 7 #include<string.h> 8 #include<stdlib.h> 9 int main() 10 { 11 int sockfd= socket(AF_INET,SOCK_STREAM,0); 12 if(sockfd<0)perror("socket"); 13 14 struct sockaddr_in server_addr; 15 memset(&server_addr,0,sizeof(server_addr)); 16 server_addr.sin_family=AF_INET; 17 server_addr.sin_port=htons(888); //this port number is owned by server,and client's port number is appointed by random 18 server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器端的ip地址 19 20 int res=connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr)); 21 if(res<0)perror("connect!!!!!!!"); 22 23 pid_t pid; 24 pid=fork(); 25 if(pid<0)perror("fork"); 26 if(0==pid)//子进程 27 { 28 char recvbuf[1024]; 29 int ret; 30 while(1) 31 { 32 memset(recvbuf,0,sizeof(recvbuf));//防止空间中的内容干涉,拖泥带水 33 ret=read(sockfd,recvbuf,sizeof(recvbuf)); 34 if(ret<0)perror("read"); 35 if(ret==0) 36 { 37 printf("peer closed!!!!!!!"); 38 break; 39 } 40 fputs(recvbuf,stdout); 41 } 42 close(sockfd); 43 } 44 else 45 { 46 char sendbuf[1024]; 47 while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL){ 48 write(sockfd,sendbuf,strlen(sendbuf)); 49 memset(sendbuf,0,sizeof(sendbuf)); 50 } 51 //exit(EXIT_SUCCESS);} 52 close(sockfd); 53 } 54 return 0; 55 }
手里拿着一把锤子,看什么都像钉子,编程界的锤子应该就是算法了吧!