网络编程中简单的点对点聊天程序
来源:互联网 发布:mac可以装bilibili吗 编辑:程序博客网 时间:2024/06/02 20:29
利用多进程实现,一个进程负责发送,一个进程负责接收!毕竟文件描述符共享(实际上是两个进程空间中不相关的文件描述符指向同一个文件)
服务器端代码:
/*server03*/#include <sys/types.h> /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h> /* superset of previous */#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#define MAX_CLIENT 10#define MAX_READ 1024void handle(int sig)//辅助杀死子进程或者父进程{ printf("recv : %d\n",sig); exit(0);}int main(){ int serv_fd,con_fd;//服务器端至少要有两个套接字文件描述符--一个用来监听,一个/其余多个用来和客户端通信 struct sockaddr_in serv_addr;//IPV4套接字结构体--服务器 struct sockaddr_in clt_addr;//IPV4套接字结构体--客户端 char addr_dst[INET_ADDRSTRLEN] = {0};//存储客户端IP地址 char buf[MAX_READ]={0};//应用程序自己的缓冲区 int optvar;//地址复用使用的参数 pid_t pid;//子进程PID socklen_t addr_len; ssize_t ret ; signal(SIGUSR1,handle);//注册新号和处理函数 serv_fd = socket(AF_INET,SOCK_STREAM,0);//建立套接字 if(-1 == serv_fd) { perror("socket"); exit(-1); } if(setsockopt(serv_fd, SOL_SOCKET,SO_REUSEADDR,&optvar,sizeof(optvar)) == -1 )//地址复用 { perror("setsockopt"); exit(-1); } /*设置地址*/ bzero(&serv_addr,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8001); serv_addr.sin_addr.s_addr = htons(INADDR_ANY); if(bind(serv_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1)//绑定端口 { perror("bind"); exit(-1); } /*一旦调用listen函数--套接字就会变成被动套接字--用来监听客户端,让客户端连接他 被动套接字--只能接受连接,不能主动发送连接 做了两个队列: 一个已经完成三次握手,建立连接的队列--客户端发connect请求被响应,已经成功完成连接 一个是未完成成三次握手的队列--正在握手 */ if(listen(serv_fd,MAX_CLIENT)== -1)//开始监听 { perror("listen"); exit(-1); } addr_len = sizeof(clt_addr); printf("Accepting connections ...\n"); if((con_fd = accept(serv_fd,(struct sockaddr *)&clt_addr,&addr_len)) == -1)//由于是点对点--所以只能处理一个客户端的连接请求 { perror("accept"); exit(-1); } printf("received from %s at PORT %d\n",inet_ntop(AF_INET,&clt_addr.sin_addr,addr_dst,sizeof(addr_dst)),ntohs(clt_addr.sin_port)); pid = fork();//创建子进程 if(pid > 0)//父进程负责读取客户端数据 { while(1) { ret = read(con_fd,buf,sizeof(buf));//读取数据 if(ret == 0) { /*如果在读的过程中,对方已关闭,TCP/IP协议会返回一个0数据包*/ printf("client close\n"); break; } else if(ret < 0) { perror("read"); exit(-1); } fputs(buf,stdout);//打印内容 memset(buf,0,sizeof(buf)); } close(serv_fd);//关闭套接字 close(con_fd); kill(pid,SIGUSR1);//发送信号给子进程--通知他死期已到 } else if(pid == 0)//子进程负责向客户端写入数据 { printf("Please input alphabet:"); while(fgets(buf,sizeof(buf),stdin) != NULL)//从标准输入获取数据 { write(con_fd,buf,strlen(buf));//给客户端发送数据 memset(buf,0,sizeof(buf));//缓冲区清理 printf("Please input alphabet:"); } } else if(pid == -1)//创建子进程错误 { perror("fork"); close(serv_fd); close(con_fd); exit(-1); } return 0;}
客户端代码
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h> /* superset of previous */#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#define MAX_BUF 1024void handle(int sig){ printf("recv : %d\n",sig); exit(0);}int main(){ int clt_fd; struct sockaddr_in serv_addr; char buf[MAX_BUF]={0}; char addr_dst[INET_ADDRSTRLEN] = {0}; ssize_t ret; pid_t pid; signal(SIGUSR1,handle); clt_fd = socket(AF_INET,SOCK_STREAM,0); if(-1 == clt_fd) { perror("socket"); exit(-1); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8001); serv_addr.sin_addr.s_addr = inet_addr("192.168.1.110"); if(connect(clt_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1) { perror("connect"); exit(-1); } printf("Connect successfully\t%s at PORT %d\n",inet_ntop(AF_INET,&serv_addr.sin_addr,addr_dst,sizeof(addr_dst)),ntohs(serv_addr.sin_port)); pid = fork(); if(pid > 0)//父进程负责给服务器端发送数据 { printf("Please input the alphabet:"); while(fgets(buf,sizeof(buf),stdin) != NULL)//从标准输入获取数据 { write(clt_fd,buf,strlen(buf));//发送数据 memset(buf,0,sizeof(buf));//缓冲器清理 printf("Please input the alphabet:"); } } else if(pid == 0)//子进程负责从服务器端获取数据 { while(1) { ret = read(clt_fd,buf,sizeof(buf));//读数据 if(ret == 0) { /*如果在读的过程中,对方已关闭,TCP/IP协议会返回一个0数据包*/ printf("server close\n"); break; } else if(ret < 0) { perror("read"); exit(-1); } fputs(buf,stdout);//打印内容 memset(buf,0,sizeof(buf)); } close(clt_fd); kill(getppid(),SIGUSR1);//发送信号给父进程--通知他死期已到 } else if(pid == -1)//创建子进程错误 { perror("fork"); close(clt_fd); exit(-1); } return 0;}
0 0
- 网络编程中简单的点对点聊天程序
- Linux网络编程学习笔记-简单点对点聊天程序--6
- Linux网络编程之简易的点对点聊天程序程序
- LINUX网络编程,简单的聊天程序
- VB 利用UDP制作简单的点对点聊天程序
- 简单的点对点聊天软件
- 简单的点对点聊天软件
- MFC实现简单点对点聊天程序
- iPhone网络编程初体验-简单的聊天程序
- iPhone之网络编程初体验-简单的聊天程序
- iPhone网络编程初体验-简单的聊天程序
- JAVA网络编程——简单的聊天程序
- 黑马程序员_网络编程之简单的聊天程序
- iPhone网络编程初体验-简单的聊天程序
- Java网络编程以及简单的聊天程序
- 网络编程之简单的多人聊天程序
- socket编程之点对点聊天程序
- c#网络编程学习笔记02_Tcp编程(中)_简单的同步tcp聊天程序
- FreeRTOS 学习五:信号量和互斥锁
- settings.xml的读取顺序问题
- 在Ubuntu Server14.04上编译Android6.0源码
- 关于知道后序序列和中序序列确定前序序列
- DatabaseMetaData的用法
- 网络编程中简单的点对点聊天程序
- Delphi 关键字详解
- python学习
- Java压缩算法性能比较
- JSP动作标签详解
- Apache2.4安装以及配置
- 在android源码编译自己的模块
- hihoCoder #1014 : Trie树(数组实现)
- ‘Window’