Linux下的TCP/IP编程----进程间通讯
来源:互联网 发布:4y4淘宝店铺装修安全吗 编辑:程序博客网 时间:2024/06/05 15:42
之前我们简单的使用多进程的方式实现了服务端的并发服务,但是这两个进程之间并不能相互通讯进行数据的交换,在本节我们简单了解一下Linux下的进程间通讯的一种方式——管道通讯。
管道通讯可以视作两个进程之间有一个管道相连接,通过这个管道来进行进程间的数据交换。首先创建管道,然后要传输数据的一方向管道中写入要传输的数据,然后接收方从管道中将数据取走,这样一来就完成了两个进程间的通讯。
int pipe(int fileds[2])创建管道:
fileds[2](文件描述符数组):创建管道时传入的用于管道IO的文件描述符。
fileds[0]:通过管道接收数据时的文件描述符,即管道的出口
fileds[1]:通过管道发送数据时的文件描述符,即管道的入口
成功时返回0,失败时返回-1
通过管道在两个进程间传输数据:
#include<stdio.h>#include<unistd.h>#define BUFF_SIZE 30int main(int argc , char *argv[]){ //用于管道IO的文件描述符 int fds[2]; //要发送的数据 char send_str[] = "Hello World"; //字符缓冲 char str_buff[BUFF_SIZE]; pid_t pid; //床架管道 pipe(fds); //创建子进程 pid = fork(); if(pid == 0){ //在子进程中向管道写入数据 write(fds[1],send_str,sizeof(send_str)); }else{ //在主进程中读取管道中的数据 read(fds[0],str_buff,BUFF_SIZE); puts(str_buff); } return 0;}
若要想实现在两个进程之间全双工的进行数据交换,就需要创建两个管道,分别对应于读写。
在知道了管道间的通讯方式之后,我们就可以用其实现一个保存数据的服务端。
#include <stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/wait.h>#include<signal.h>#include<string.h>#include<sys/socket.h>#include<arpa/inet.h>#include<stdbool.h>#define BUFF_SIZE 100void error_handling(char * message);void read_child_proc(int sig);int main(int argc , char *argv[]){ //服务端和客户端socket int server_socket; int client_socket; //服务端和客户端地址 struct sockaddr_in server_addr; struct sockaddr_in client_addr; //用于创建通讯管道 int fds[2]; //用于保存进程ID pid_t pid; //信号量结构体变量 struct sigaction act; //用于保存socket地址长度 socklen_t addr_size; //用于保存字符串长度 int str_len; //用于记录设置信号量的结果 int state; //字符缓冲 char buff[BUFF_SIZE]; //用于控制程序的结束与否 bool is_running = true; //检查传入的参数个数是否合法 if(argc!=2){ printf("Usage : %s <port> \n",argv[0]); exit(1); } //初始化信号量机制 act.sa_handler = read_child_proc; act.sa_flags = 0; sigemptyset(&act.sa_mask); state = sigaction(SIGCHLD,&act,0); //初始化socket server_socket = socket(PF_INET,SOCK_STREAM,0); memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(atoi(argv[1])); //绑定地址 if(bind(server_socket,(struct sockaddr *) &server_addr,sizeof(server_addr)) == -1){ error_handling("bind() error"); } //设置监听 if(listen(server_socket,5) == -1){ error_handling("listen() error"); } //创建管道 pipe(fds); //创建子进程,用于复制保存数据 pid = fork(); /**子进程运行区**/ if(pid == 0){ //创建指向保存文件的文件描述符 FILE *fp = fopen("savedMsg.txt","wt"); //创建字符缓冲 char msg_buff[BUFF_SIZE]; //从管道读取的行数 int read_line = 0; //每次从管道读取的长度 int read_len; for(;read_line<10;read_line++){ //从管道中读取到数据,并记录每次读取到的长度 read_len = read(fds[0],msg_buff,BUFF_SIZE); //向文件中写入数据 fwrite((void *) msg_buff,1,read_len,fp); } //关闭文件 fclose(fp); return 0; /**子进程运行结束**/ } while(is_running){ addr_size = sizeof(client_addr); client_socket = accept(server_socket,(struct sockaddr *) &client_addr,&addr_size); if(client_socket == -1){ continue; }else{ puts("new client connected"); } //新建立一个进程,用于接收客户端发来的数据,并将数据写入管道中 pid = fork(); if(pid == 0){ close(server_socket); //读取来自客户端的消息 while(str_len = read(client_socket,buff,BUFF_SIZE) != 0){ puts(buff); //向客户端返回数据 write(client_socket,buff,str_len); //向管道中写入数据 write(fds[1],buff,str_len); } //数据读写完毕,关闭和客户端的连接 close(client_socket); puts("client disconnected"); return 0; }else{ close(client_socket); } }close(server_socket);return 0;}/**子进程处理函数**/void read_child_proc(int sig){ pid_t pid; int status; pid = waitpid(-1,&status,WNOHANG); printf("remove proc id : %d \n",pid);}/**出错处理函数**/void error_handling(char * message){ fputs(message,stderr); fputc('\n',stderr); exit(1);}
0 0
- Linux下的TCP/IP编程----进程间通讯
- Linux下的TCP/IP编程----进程及多进程服务端
- linux下tcp/ip编程
- linux下的进程间通讯
- linux下的进程间通讯
- Linux下的TCP/IP编程----socket的可选项
- Linux TCP/IP通讯建立
- linux下tcp-ip栈和Netfilter的分析编程
- Linux下的TCP/IP编程----基础篇
- Linux下的TCP/IP编程----实践篇
- Linux下的TCP/IP编程----UDP篇
- Linux下的TCP/IP编程----UDP实践篇
- Linux下的TCP/IP编程----线程及多线程服务端
- linux下TCP/IP网络编程
- Linux下TCP/IP网络编程
- Linux下TCP/IP socket 编程二
- linux应用编程----进程间通讯kill
- Linux下的TCP/IP编程------基于TCP的半关闭
- Google I/O 2015 为 Android 开发者带来了哪些福利?
- 第十三周【项目4-立体类族共有的抽象类】
- 第9周课后实践 阅读程序,请写出这些程序的运行结果(3)
- OpenGL 超级宝典 读书笔记-1
- Python 开发简单爬虫 学习笔记1
- Linux下的TCP/IP编程----进程间通讯
- Convert mat to numpy array , numpy gradient
- ps -aux|grep 详细信息
- 天线接口:SMA、TNC 有什么差别?
- linux grep命令
- mysql 入门基础(3)—数据库增删查改
- postgresql
- JPush获取regId
- 学习数学系列<一>