linux网络编程多进程并发服务器
来源:互联网 发布:js sort函数 编辑:程序博客网 时间:2024/04/28 23:54
服务器端代码
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <pthread.h>#define PORT 1234#define MAXSIZE1024struct ARG{int connfd;struct sockaddr_in clientAddr;};void savedata(char *recvbuf, int len, char *cli_data){static int index = 0;int i = 0;while (i < len-1){cli_data[index++] = recvbuf[i];i++;}cli_data[index] = '\0';}static int clientProcess(int connfd, struct sockaddr_in clientSock){int num = 0;int i = 0;char recvBuf[MAXSIZE];char sendBuf[MAXSIZE];char clientName[MAXSIZE];char cli_data[MAXSIZE];struct timeval val;fd_set fd;int ret;val.tv_sec = 0;val.tv_usec = 0;num = recv(connfd, clientName, MAXSIZE, 0);if (num < 0){printf("recv clientName message from client!\n");return -1;}clientName[strlen(clientName)-1] = '\0';printf("You got's a connection from %s, client name is %s\n",inet_ntoa(clientSock.sin_addr), clientName);while (1){FD_ZERO(&fd);FD_SET(connfd, &fd);ret = select(FD_SETSIZE, &fd, NULL, NULL, &val);num = recv(connfd, recvBuf, MAXSIZE, 0);if (num == 0){printf("Client(%s) closed connection\nUser's data:%s\n",clientName, cli_data);close(connfd);return -1;}recvBuf[strlen(recvBuf)-1] = '\0';printf("received client (%s) message :%s\n", clientName, recvBuf);//保存接收到的信息savedata(recvBuf, num, cli_data);//将接收到的客户端数据加密返回给客户端for (i=0; i<num-1; i++) {if ((recvBuf[i]>='a' && recvBuf[i]<='z') || (recvBuf[i]>='A' && recvBuf[i]<='Z')){recvBuf[i] = recvBuf[i] + 3;if ((recvBuf[i]>'Z' && recvBuf[i]<'Z'+3) || (recvBuf[i]>'z')){recvBuf[i] = recvBuf[i] -26;}}sendBuf[i] = recvBuf[i];}sendBuf[num-1] = '\0';send(connfd, sendBuf, MAXSIZE, 0);memset(sendBuf, 0, MAXSIZE);memset(recvBuf, 0, MAXSIZE);}close(connfd);return 1;}void *funThread(void *arg){struct ARG *info;info = (struct ARG *)arg;clientProcess(info->connfd, info->clientAddr);free(arg);arg = NULL;pthread_detach(pthread_self());pthread_exit(NULL);}int main(int argc, char **argv){int listenfd, connfd;pthread_t pid_t;struct ARG *arg;struct sockaddr_in serveraddr;struct sockaddr_in clientaddr;socklen_t len;listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd < 0){printf("Creating socket failed!\n");return -1;}int opt = SO_REUSEADDR;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));bzero(&serveraddr, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(PORT);serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0){printf("bind fails!\n");return -1;}if (listen(listenfd, 5) < 0){printf("listen fails!\n");return -1;}len = sizeof(clientaddr);for (;;){connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &len);if (connfd < 0){printf("accept fails!\n");return -1;}arg = (struct ARG *)malloc(sizeof(struct ARG));if (arg == NULL){printf("malloc memory fails!\n");return -1;}memset(arg, 0, sizeof(struct ARG));arg->connfd = connfd;memcpy((void *)&arg->clientAddr, &clientaddr, sizeof(clientaddr));//处理客户端信息if (pthread_create(&pid_t, NULL, funThread, (void *)arg) < 0){printf("Create thread fails!\n");return -1;}}close(listenfd);}
客户端代码:
#include <string.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#define PORT1234#define MAXSIZE 1024static int clientProcess(FILE *fp, int connfd){char readLine[MAXSIZE];char recvLine[MAXSIZE];int num;printf("connect to server success!\n");printf("Input client's name:");if (fgets(readLine, MAXSIZE, fp) == NULL){printf("fgets fails!\n");return -1;}send(connfd, readLine, MAXSIZE, 0);while (fgets(readLine, MAXSIZE, fp) != NULL){if (strncmp(readLine, "quit", strlen("quit")) == 0){fflush(stdin);exit(-1);}send(connfd, readLine, strlen(readLine), 0);num = recv(connfd, recvLine, MAXSIZE, 0);if (num < 0){printf("received fails!\n");return -1;}recvLine[num-1] = '\0';printf("Server message:%s\n", recvLine);}return 1;}int main(int argc, char **argv){int sockfd;struct sockaddr_in serverSock;struct hostent *he;if (argc != 2){printf("Usage: %s <IP Address>\n", argv[0]);return -1;}he = gethostbyname(argv[1]);if (he == NULL){printf("gethostbyname fails!\n");return -1;}sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){printf("Create socket fails!\n");return -1;}bzero(&serverSock, sizeof serverSock);serverSock.sin_family = AF_INET;serverSock.sin_port = htons(PORT);serverSock.sin_addr = *((struct in_addr *)he->h_addr);if (connect(sockfd, (struct sockaddr *)&serverSock, sizeof serverSock) < 0){printf("connect fails!\n");return -1;}clientProcess(stdin, sockfd);close(sockfd);return 1;}编译运行。
首先运行服务器程序,然后打开两个客户端终端并连接上服务器程序。如下图所示:
服务器运行情况:
客户端1运行情况:
客户端2运行情况:
仔细看服务端运行情况就能看到问题,当客户端1退出后,执行
savedata(recvBuf, num, cli_data);的信息能够打印出来,当客户端2退出时,结果却不打印保存的信息。这是为什么?这就是非线程安全的问题。
- linux网络编程多进程并发服务器
- linux网络编程多进程并发服务器
- 网络编程(5)多进程并发服务器
- Linux网络编程——tcp并发服务器(多进程)
- Linux网络编程——tcp并发服务器(多进程)
- Linux网络编程9 -- 简单总结Select改善多进程并发服务器
- UNIX网络编程——并发服务器(多进程)
- 《Unix网络编程》 多进程并发服务器基本模型
- 多进程并发服务器编程
- 多进程并发服务器编程
- Linux并发服务器编程之多进程并发服务器
- linux僵死进程与并发服务器编程
- 【Unix 网络编程】服务器网络编程模型——多进程并发模型
- linux网络编程:并发服务器的模型
- Linux网络编程之高级并发服务器
- Linux网络编程之简单并发服务器
- Linux网络编程之高级并发服务器
- Linux网络编程之简单并发服务器
- (译)在cocos2d里面如何使用物理引擎box2d:弹球
- 通过show status 来优化MySQL数据库
- 杭电1018 阶乘位数
- jquery 结构
- 根据生肖选择年份控件
- linux网络编程多进程并发服务器
- PPT放映期间如何插入音频
- MyEclipse官方下载地址
- oracle order by排序总结
- 域名解析和CDN 原理
- [教程] 【转】Android 通过软引用实现图片缓存,防止内存溢出 [复制链接]
- 给年轻程序员的建议
- SQL注入漏洞全接触--入门篇
- struts2中jsp、ftl模板html静态化