linux简单进程间socket通信

来源:互联网 发布:中国手机网民最新数据 编辑:程序博客网 时间:2024/05/17 09:06

socket多用于网络通信,但将服务地址设为本机地址之后,即可实现本机进程间socket通信,利用socket可以在进程间方便地传输数据。

在linux平台上还支持AF_UNIX通信,而不必设定本机地址,这种socket通信类型在windows平台上并不适用。

下面模拟三个进程间利用socket通信,server进程负责接收客户端进程1和2的通信请求并且将通信内容转交给对端。对于server端利用两个线程分别接收两个客户端的连接请求,并且开了两个socket,这种方式只是简单的模拟实现,是效率低下的一种方式。示例代码如下:

服务进程server

</pre><p></p><pre name="code" class="cpp">#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <netinet/in.h>#include <string.h> //for memset#include <sys/stat.h>#include <sys/param.h>#include <stdarg.h>// 设定端口号#define RPC_PORT_CSDK6666#define RPC_PORT_UI6665#define BUFF_SIZE 1024#define LOG_FILE"daemon.log"char recv_ui[BUFF_SIZE];char recv_csdk[BUFF_SIZE];// 通过可变参数写日志文件void writeLog(const char* format, ...){va_list argp;FILE* flog;va_start(argp, format);flog = fopen(LOG_FILE, "a");vfprintf(flog, format, argp);fclose(flog);va_end(argp);}void recvMessage(int fd, char* buf){int ret;if(buf == NULL){writeLog("SERVER: recieve message buffer is null!\n");return;}ret = recv(fd, buf, BUFF_SIZE, 0);buf[ret] = '\0';if(ret > 0){if(buf == recv_csdk)writeLog("SERVER_CSDK: received %d message--%s\n", strlen(buf), buf);elsewriteLog("SERVER_UI: received %d message--%s\n", strlen(buf), buf);}}void sendMessage(int fd, const char* toWhom){if(toWhom == NULL){writeLog("SERVER:write to whom is null\n");return;}else if(toWhom == "UI"){if( strlen(recv_csdk) == 0){return;}else{recv_csdk[strlen(recv_csdk)] = '\0';send(fd, recv_csdk, strlen(recv_csdk), 0);writeLog("SERVER: write to fd %d message -- %s\n", fd, recv_csdk);memset(recv_csdk, 0, BUFF_SIZE);}}else if(toWhom == "CSDK"){if( strlen(recv_ui) == 0){return;}else{recv_ui[strlen(recv_ui)] = '\0';send(fd, recv_ui, strlen(recv_ui), 0);writeLog("SERVER: write to fd %d message %d bytes -- %s\n", fd, strlen(recv_ui), recv_ui);memset(recv_ui, 0, BUFF_SIZE);}}}void initDaemon(void){pid_t pid;int i;if( (pid = fork()) < 0)writeLog("SERVER: daemon fork 1 failed!\n");else if(pid > 0)exit(0); // 退出父进程setsid();//第一个子进程成为会话组长和进程组长, 并与控制终端分离if( (pid = fork()) < 0)writeLog("SERVER: daemon fork 2 failed!\n");else if( pid > 0)exit(0);// 退出第一个子进程for( i=0; i<NOFILE; ++i)//关闭打开的文件描述符close(i);//chdir("/tmp"); //改变工作目录到/tmpumask(0);//重设创建文件掩码n return;}void serveCSDK(void){int ret;char buff[BUFF_SIZE];fd_set readFds, testFds;int connFd, listenFd;;struct sockaddr_in serverAddr;// 创建socketlistenFd = socket(AF_INET, SOCK_STREAM, 0);if( listenFd < 0){writeLog("SERVER: create socket failed!\n");exit(EXIT_FAILURE);}// 设定服务端地址及端口memset(&serverAddr, 0, sizeof(serverAddr));serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);// INADDR_ANY--自动查找本机地址serverAddr.sin_port = htons(RPC_PORT_CSDK);// 绑定ret = bind(listenFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));if(ret < 0){writeLog("SERVER_CSDK: bind socket failed!\n");exit(EXIT_FAILURE);}// 监听ret = listen(listenFd, 10);// 最大接受10个连接if( ret < 0){writeLog("SERVER_CSDK: listen socket failed!\n");exit(EXIT_FAILURE);}FD_ZERO(&readFds);FD_SET(listenFd, &readFds);while(1){testFds = readFds;// 等待连接writeLog("SERVER_CSDK: waiting for connection ...\n");//ret = select(FD_SETSIZE, &testfds, (fd_set *)NULL, (fd_set *)NULL, )connFd = accept(listenFd, (struct sockaddr*)NULL, NULL);if( connFd  < 0 ) {writeLog("SERVER_CSDK: accept socket failed!\n");exit(EXIT_FAILURE);}while(1){recvMessage(connFd, recv_csdk);sendMessage(connFd, "CSDK");}}}void serveUI(void){int ret;char buff[BUFF_SIZE];int connFd, listenFd;;struct sockaddr_in serverAddr;// 创建socketlistenFd = socket(AF_INET, SOCK_STREAM, 0);if( listenFd < 0){writeLog("SERVER: create socket failed!\n");exit(EXIT_FAILURE);}// 设定服务端地址及端口memset(&serverAddr, 0, sizeof(serverAddr));serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);// INADDR_ANY--自动查找本机地址serverAddr.sin_port = htons(RPC_PORT_UI);// 绑定ret = bind(listenFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));if(ret < 0){writeLog("SERVER_UI: bind socket failed!\n");exit(EXIT_FAILURE);}// 监听ret = listen(listenFd, 10);if( ret < 0)// 最大接受10个连接{writeLog("SERVER_UI: listen socket failed!\n");exit(EXIT_FAILURE);}while(1){// 等待连接writeLog("SERVER_UI: waiting for connection ...\n");connFd = accept(listenFd, (struct sockaddr*)NULL, NULL);if( connFd  < 0 ) {writeLog("SERVER_UI: accept socket failed!\n");exit(EXIT_FAILURE);}while(1){recvMessage(connFd, recv_ui);sendMessage(connFd, "UI");}}}int main(void){int ret;initDaemon();writeLog("SERVER: daemon create succeed\n");pthread_t th_csdk, th_ui;ret = pthread_create(&th_csdk, NULL, serveCSDK, NULL);if(ret != 0){writeLog("SERVER: create csdk server thread failed!\n");exit(EXIT_FAILURE);}// 脱离线程ret = pthread_detach(th_csdk);if(ret != 0){writeLog("SERVER: detach the csdk thread failed!\n");exit(EXIT_FAILURE);}// 执行UI服务serveUI();return 0;} 

客户进程1 process1

#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <netinet/in.h>#include <string.h> //for memset#include <sys/stat.h>#include <sys/param.h>// 设定端口号#define RPC_PORT6665#define BUFF_SIZE1024int main(void){int ret;int socketServer, socketNew;int clientFd, connFd;struct sockaddr_in serverAddr;// 创建socketclientFd = socket(AF_INET, SOCK_STREAM, 0);if( clientFd == -1){printf("CLIENT: socket create failure!\n");exit(EXIT_FAILURE);}// 设定服务端地址及端口memset(&serverAddr, 0, sizeof(serverAddr));serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);// INADDR_ANY--自动查找本机地址serverAddr.sin_port = htons(RPC_PORT);ret = connect(clientFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));if( ret < 0){printf("CLIENT: connect failure!\n");exit(EXIT_FAILURE);}char sendBuf[BUFF_SIZE] = "Hello, I Am UI";char recvBuf[BUFF_SIZE];memset(recvBuf, 0, BUFF_SIZE);while(1){ret = send(clientFd, sendBuf, strlen(sendBuf), 0);if(ret > 0)printf("CLIENT_UI: send message succeed!\n");ret = recv(clientFd, recvBuf, BUFF_SIZE, MSG_DONTWAIT);if(ret > 0)printf("CLIENT_UI: received message: %s\n", recvBuf);sleep(3);}return 0;}

客户进程2 process2

#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <netinet/in.h>#include <string.h> //for memset#include <sys/stat.h>#include <sys/param.h>// 设定端口号#define RPC_PORT6666#define BUFF_SIZE1024int main(void){int ret;int socketServer, socketNew;int clientFd, connFd;struct sockaddr_in serverAddr;// 创建socketclientFd = socket(AF_INET, SOCK_STREAM, 0);if( clientFd == -1){printf("CLIENT_CSDK: socket create failure!\n");exit(EXIT_FAILURE);}// 设定服务端地址及端口memset(&serverAddr, 0, sizeof(serverAddr));serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);// INADDR_ANY--自动查找本机地址serverAddr.sin_port = htons(RPC_PORT);ret = connect(clientFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));if( ret < 0){printf("CLIENT_CSDK: connect failure!\n");exit(EXIT_FAILURE);}char sendBuf[BUFF_SIZE] = "Hello, I Am CSDK";char recvBuf[BUFF_SIZE];memset(recvBuf, 0, BUFF_SIZE);while(1){ret = send(clientFd, sendBuf, strlen(sendBuf), 0);if(ret > 0)printf("CLIENT_CSDK: send message succeed!\n");ret = recv(clientFd, recvBuf, BUFF_SIZE, MSG_DONTWAIT);if(ret > 0)printf("CLIENT_CSDK: received message: %s\n", recvBuf);sleep(3);}return 0;}




0 0
原创粉丝点击