参考链接:Linux 网络编程详解三(p2p点对点聊天)https://www.cnblogs.com/zhanggaofeng/p/6131783.html?from=singlemessage&isappinstalled=0
服务器
void handler(int signo){
if(signo==SIGUSR1){
printf("child process exit\n");
exit(1);
}
}
int main(){
int listenfd=socket(PF_INET,SOCK_STREAM,0);
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(8001);
addr.sin_addr.s_addr=inet_addr("127.0.0.1");
int optval=1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
bind(listenfd,(struct sockaddr*)&addr,sizeof(addr));
listen(listenfd,5);
struct sockaddr_in peer_addr;
socklen_t peer_addr_len;
int newconn=accept(listenfd,(struct sockaddr*)&peer_addr,&peer_addr_len);
if(newconn==-1){
perror("connect fail");
close(newconn);
return -1;
}
else
printf("accept by %s\n", inet_ntoa(peer_addr.sin_addr));
pid_t pid=fork();
if(pid==-1){
perror("fork");
return -1;
}
if(pid>0){ //父进程接收客户端信息,打屏
while(1){
char buf[1024];
int ret=read(newconn,buf,sizeof(buf));
if(ret>0)
fputs(buf,stdout); //write(STDOUT_FILENO, buf, ret); //打印到屏幕上
else if(ret==0){
printf("peer have close\n");
close(newconn);
break;
}
else{ //recv error
printf("read<0,error\n");
break;
}
memset(buf,0,sizeof(buf));
}
//发送信号,关闭子进程
kill(pid,SIGUSR1); // kill signal
close(listenfd);
close(newconn);
//wait子进程
int ret=0;
while(1)
{
ret=wait(NULL);
printf("子进程pid=%d\n",ret);
if(ret==-1)
{
if(errno==EINTR)
continue;
break;
}
}
}
else if(pid==0){ //子进程读取用户输入,发送给客户端
close(listenfd); //关闭服务器监听套接字
signal(SIGUSR1,handler); //安装信号
char buf[1024];
while(fgets(buf,sizeof(buf),stdin)!=NULL){ //while(read(STDIN_FILENO, sendbuf, 1024) == -1)
write(newconn,buf,strlen(buf));
memset(buf,0,sizeof(buf));
}
}
}
客户端
int main(){
int sockfd=socket(PF_INET,SOCK_STREAM,0);
struct sockaddr_in svr_addr;
svr_addr.sin_family=AF_INET;
svr_addr.sin_port=htons(8001);
svr_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
int ret=connect(sockfd,(struct sockaddr*)&svr_addr,sizeof(svr_addr));
if(ret==-1){
perror("connect");
exit(1);
}
else
printf("connect server sucess\n");
pid_t pid=fork();
if (pid == -1){
perror("fork() err");
return -1;
}
if(pid>0){ //父进程
char buf[1024]={0};
while(fgets(buf,sizeof(buf),stdin)!=NULL){
write(sockfd,buf,strlen(buf));
memset(buf,0,sizeof(buf));
}
}
else if(pid==0){//子进程接收信息,打屏
while(1){
char buf[1024];
int ret=read(sockfd,buf,sizeof(buf));
if(ret>0)
fputs(buf,stdout); //打屏
else if(ret==0){
printf("peer have close\n");
close(sockfd);
break;
}
else{
printf("read<0,error\n");
break;
}
memset(buf,0,sizeof(buf));
}
close(sockfd);
kill(getppid(),SIGKILL);
exit(1);
}
return 0;
}