p2p服务程序开发

来源:互联网 发布:雍正王朝 知乎 编辑:程序博客网 时间:2024/06/05 02:05

传智扫地僧课程学习笔记。



中间直接复制代码的时候,出了一个错误,

说明下,

客户端,就一个套接字,所以收发都是通过它来完成,

服务器端,是通过accept返回的链接来进行通信的,不是最开始那个(因为已经用于listen了),



tcp/ip是流式的,

当客户端主动关闭后,会发送一个FIN信号,


可是你通过 ps -u | grep 用户名,

发现,服务器程序还在运行,

原来是服务器有2个进程,

一个进程检测到客户端关闭后,就关闭了,

另一个进程,也就是子进程,没人管,就一直嘎在那,

所以我们需要服务器父进程,发一个信号给子进程,让它关闭,


下面是代码,

在信号发送中,有个地方不明白啊,??怎么在父进程中kill的pid是自己的pid,不是应该是子进程的id吗,

这是服务器代码,

#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 <netinet/in.h>#include <sys/socket.h>void handle( int num){printf("recv num:%d\n", num);exit( 0);}int main(){int sockfd = 0;signal( SIGUSR1, handle);sockfd = socket( PF_INET, SOCK_STREAM, 0);if( -1 == sockfd ){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("127.0.0.1");int optval = 1;if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))< 0){perror("setsockopt bind\n");exit(0);}if( bind( sockfd, (struct sockaddr *)&srvaddr, sizeof( srvaddr)) <0){perror("socket\n");exit( 0);}if( listen( sockfd, SOMAXCONN) <0){perror( "fun listen\n");exit( 0);}//struct sockaddr peeraddr, //socklen_t peerlen;struct sockaddr_in perraddr;socklen_t perrlen = sizeof( perraddr);unsigned int conn = 0;conn = accept( sockfd, (struct sockaddr *)&perraddr, (socklen_t *)&perrlen);if( conn == -1){perror("fun listen\n");exit( 0);}int pid;pid = fork();if( pid>0 ){char revbuf[1024] = {0};int ret;while(1){ret = read( conn, revbuf, sizeof( revbuf));if( ret==0){printf("duifang guanbile");break;}else if( ret<0){perror("read fail\n");exit( 0);}fputs( revbuf, stdout);//write( conn, revbuf, ret);memset( revbuf, 0, sizeof( revbuf));}kill( pid, SIGUSR1);}else {char sendbuf[1024] = {0};while( fgets(sendbuf, sizeof(sendbuf), stdin)!=NULL){write( conn, sendbuf, strlen(sendbuf));//read( sockfd, revbuf, sizeof(revbuf));//fputs( revbuf, stdout);//memset( revbuf, 0, sizeof(revbuf));memset( sendbuf, 0, sizeof(sendbuf));}}close( conn);close( sockfd);return 0;}/*accept返回一个新的,*/



这是客户端代码,

#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 <netinet/in.h>#include <sys/socket.h>int main(){int sockfd = 0;sockfd = socket( PF_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("127.0.0.1");if( connect( sockfd, ( struct sockaddr*)(&srvaddr), sizeof( srvaddr))<0){perror("connect");exit( 0);}int pid = 0;pid = fork();if( pid > 0){//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));}}else if( pid == 0){char revbuf[1024] = {0};while( 1){read( sockfd, revbuf, sizeof(revbuf));fputs( revbuf, stdout);memset( revbuf, 0, sizeof(revbuf));}}close( sockfd);return 0;}





0 0
原创粉丝点击