多进程并发C/S通信基本模型及实现
来源:互联网 发布:调节阀选型计算软件 编辑:程序博客网 时间:2024/06/03 23:47
本例实现如下功能:
服务端接收来自客户端发送过来的字符串,将小写转换为大写后发送回客户端。
其中,每一个新客户端连接后,服务端主进程为此客户端创建一个子进程进行数据的处理。
多进程并发服务端代码:
/*server.c*/#include <stdio.h>#include <string.h>#include <netinet/in.h>#include <arpa/inet.h>#include <signal.h>#include <sys/wait.h>#include <sys/types.h>#include <stdlib.h>#include <errno.h>#include <sys/socket.h>#define BUFSIZE 666#define SERV_PORT 8888int main(){ struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int listenfd, connfd; char buf[BUFSIZE]; char str[INET_ADDRSTRLEN]; int i, n; pid_t pid; listenfd = socket(AF_INET, SOCK_STREAM, 0); //打开一个网络通讯端口,分配一个文件描述符listenfd bzero(&servaddr, sizeof(servaddr)); //清空服务端套接字 servaddr.sin_family = AF_INET; //地址采用IPv4地址 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//地址从主机字节顺序转换成网络字节顺序 servaddr.sin_port = htons(SERV_PORT); //端口号从主机字节顺序转换成网络字节顺序 /*将文件描述符listenfd和服务器地址绑定在一起*/ bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); /*声明listenfd处于监听状态,链接个数限制为5*/ listen(listenfd, 20); printf("等待连接....\n"); while(1){ cliaddr_len = sizeof(cliaddr); /*connfd文件描述符用于和客户端通信,服务端调用accept()接受连接*/ connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_len); pid = fork(); if(pid == 0){ //创建一个子进程处理数据 close(listenfd);//关闭子进程端的监听 while(1){ /*从connfd文件描述符指向的文件读取数据*/ n = read(connfd, buf, BUFSIZE); if(n == 0){ printf("另一端已关闭\n"); break; } /*服务端打印*/ printf("从地址%s 端口号%d 接收到数据\n", (char*)inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port)); /*将buf转化为大写后写入connfd*/ for(i = 0; i < n;i++ ){ buf[i] = toupper(buf[i]); } write(connfd, buf, n); } close(connfd);//处理完毕关闭连接 exit(0); }else if(pid > 0){ //父进程 close(connfd);//任务交由子进程处理,父进程关闭 }else{ printf("fork err\n"); } if(n == 0 || n == -1){ break; } } return 0;}
多进程并发客户端代码:
/*client.c*/#include <stdio.h>#include <string.h>#include <unistd.h>#include <netinet/in.h>#define BUFSIZE 666#define SERV_PORT 8888int main(int argc, char *argv[]){ struct sockaddr_in servaddr; char buf[BUFSIZE]; int sockfd, n; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); /*连接服务器*/ connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); while(fgets(buf, BUFSIZE, stdin) != NULL){ write(sockfd, buf, strlen(buf)); /*接收服务端数据*/ n = read(sockfd, buf, BUFSIZE); if(n == 0){ printf("server closed\n"); }else{ /*打印输出buf*/ write(STDOUT_FILENO, buf, n); } } close(sockfd); return 0;}
执行测试:
yu@ubuntu:~/Linux/219/duojincheng$ lsclient.c server.cyu@ubuntu:~/Linux/219/duojincheng$ gcc -o server server.cyu@ubuntu:~/Linux/219/duojincheng$ gcc -o client client.cyu@ubuntu:~/Linux/219/duojincheng$ ./server等待连接....从地址127.0.0.1 端口号32874 接收到数据从地址127.0.0.1 端口号32874 接收到数据从地址127.0.0.1 端口号32875 接收到数据从地址127.0.0.1 端口号32874 接收到数据从地址127.0.0.1 端口号32875 接收到数据
另开一终端执行客户端:
yu@ubuntu:~/Linux/219/duojincheng$ ./clienthey guysHEY GUYSguole byeGUOLE BYE
另开一终端执行客户端:
yu@ubuntu:~/Linux/219/duojincheng$ ./clientnihao ma wo hen hao neNIHAO MA WO HEN HAO NEzai jianZAI JIANssssssssssssssSSSSSSSSSSSSSS
0 0
- 多进程并发C/S通信基本模型及实现
- 多线程并发C/S基本通信模型及实现
- socket编程 -- 基于TCP协议的C/S通信模型及实现
- socket编程 -- 基于UDP协议的C/S通信模型及实现
- C-S基本模型
- TCP C/S 多进程模型
- 《Unix网络编程》 多进程并发服务器基本模型
- C/S通信模型与B/S通信模型介绍
- C/S通信模型与B/S通信模型介绍
- 简单高并发C/S模型
- Nginx 多进程模型是如何实现高并发的?
- C语言实现简易网络进程及线程间通信
- Linux Socket通信 C/S模型
- C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (客户端实现)
- C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (服务器实现)
- C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (服务器实现)
- C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (客户端实现)
- socket编程--TCP客户/服务器模型 (c/s)及基本函数
- 年后跳槽如何准备?(前端方向)
- 算法竞赛入门 组合数
- [oj]樱花对称问题
- Basic C++ Container classes summary(Array, Vector, List)
- jdk自带多线程处理神器Executor
- 多进程并发C/S通信基本模型及实现
- poj 3087 Shuffle'm Up
- 【hdu2049】考新郎——错位排序+排列组合
- Android学习一
- Service用法概述
- 安卓 设置圆角图片
- BZOJ_P1412 [ZJOI2009]狼和羊的故事(网络流+最大流最小割)
- MFC几个重要的基类
- 3261: 最大异或和 可持久化trie