实践:使用socket实现跨进程通信(C语言)
2021/9/20 7:05:40
本文主要是介绍实践:使用socket实现跨进程通信(C语言),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
功能描述
使用socket通信,实现服务端功能和客户端功能,并进行消息的交互,实现跨进程通信。
相关代码
- test_socket.h
#ifndef __TEST_SOCKET_H__ #define __TEST_SOCKET_H__ #define SOCK_ERR(fmt...) do { \ printf("[SOCK]" fmt); \ printf("\r\n"); \ } while(0) #define VOS_OK 0 #define VOS_ERR 1 #define VOS_TRUE 1 #define VOS_FALSE 0 typedef void VOID; typedef char CHAR; typedef int INT32; typedef unsigned char UINT8; typedef unsigned short UINT16; typedef unsigned int UINT32; typedef unsigned long long UINT64; #define SOCK_PROCESS_TYPE_NAME_SERVER "server" #define SOCK_PROCESS_TYPE_NAME_CLIENT "client" #define SOCK_PROCESS_TYPE_SERVER 0 #define SOCK_PROCESS_TYPE_CLIENT 1 #define SOCK_DEFAULT_DST_ADDR "127.0.0.1" #define SOCK_DEFAULT_DST_PORT 1500 typedef struct { UINT16 family; UINT16 port; UINT32 addr; UINT8 resv[8]; } SOCK_ADDR_S; typedef struct { UINT32 type; CHAR* addr; UINT16 port; } SOCK_PARA_S; #endif
- test_socket.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include "test_socket.h" VOID SOCK_InitPara(SOCK_PARA_S *pPara, int argc, char *argv[]) { argc--; argv++; if (argc > 0 && strcmp(SOCK_PROCESS_TYPE_NAME_CLIENT, argv[0]) == 0) { pPara->type = SOCK_PROCESS_TYPE_CLIENT; } else { pPara->type = SOCK_PROCESS_TYPE_SERVER; } if (argc > 1) { pPara->addr = argv[1]; } else { pPara->addr = SOCK_DEFAULT_DST_ADDR; } if (argc > 2) { pPara->port = (UINT16)atol(argv[2]); } else { pPara->port = SOCK_DEFAULT_DST_PORT; } } UINT32 SOCK_MainServer(SOCK_PARA_S *pPara) { INT32 ret; // socket INT32 serverHandle = socket(AF_INET, SOCK_STREAM, 0); if (serverHandle == -1) { SOCK_ERR("socket Fail!"); return VOS_ERR; } SOCK_ERR("socket(%d) create ok", serverHandle); // bind SOCK_ADDR_S addr = {0}; addr.family = AF_INET; addr.port = htons(pPara->port); addr.addr = inet_addr(pPara->addr); ret = bind(serverHandle, (struct sockaddr *)&addr, sizeof(SOCK_ADDR_S)); if (ret < 0) { SOCK_ERR("socket bind Err(%d)!", ret); return VOS_ERR; } // listen ret = listen(serverHandle, 5); if (ret != VOS_OK) { SOCK_ERR("socket listen Err(%d)!", ret); return VOS_ERR; } SOCK_ERR("socket accept ..."); // accept INT32 clientHandle; SOCK_ADDR_S clientAddr; UINT32 clientAddrLen = sizeof(SOCK_ADDR_S); // 注意:这里得是有效值 while (VOS_TRUE) { clientHandle = accept(serverHandle, (struct sockaddr *)&clientAddr, &clientAddrLen); if (clientHandle == -1) { SOCK_ERR("socket accept Fail(%d)", clientHandle); } else { SOCK_ERR("socket accept Succ"); ret = send(clientHandle, "Hello World!", 12, 0); if (ret == -1) { SOCK_ERR("socket send Fail"); } else { SOCK_ERR("socket send Succ"); } } } } UINT32 SOCK_MainClient(SOCK_PARA_S *pPara) { INT32 ret; // socket INT32 serverHandle = socket(AF_INET, SOCK_STREAM, 0); if (serverHandle == -1) { SOCK_ERR("socket Fail!"); return VOS_ERR; } SOCK_ERR("socket(%d) create ok", serverHandle); // connet SOCK_ADDR_S addr = {0}; addr.family = AF_INET; addr.port = htons(pPara->port); addr.addr = inet_addr(pPara->addr); ret = connect(serverHandle, (struct sockaddr *)&addr, sizeof(SOCK_ADDR_S)); if (ret == -1) { SOCK_ERR("socket connet Fail(%d)!", ret); return VOS_ERR; } char buf[100] = {0}; ret = recv(serverHandle, buf, 100, 0); if (ret == -1) { SOCK_ERR("socket recv Fail(%d)!", ret); return VOS_ERR; } SOCK_ERR("socket recv Succ(%s)!", buf); } int main(int argc, char *argv[]) { SOCK_PARA_S para; SOCK_InitPara(¶, argc, argv); SOCK_ERR("test socket start"); if (para.type == SOCK_PROCESS_TYPE_SERVER) { (VOID)SOCK_MainServer(¶); } else { (VOID)SOCK_MainClient(¶); } SOCK_ERR("test socket end"); return VOS_OK; }
功能演示
- 第一步:打开Linux操作窗口,启动Server进程。
./test_socket server 127.0.0.1 1500
- 第二步:打开另一个Linux操作窗口,启动Client进程。可以观察到Client收到Server的消息,同时观察Server日志可以发现发送成功。
./test_socket client 127.0.0.1 1500
- 第三步:查看抓包。可以看到对应的TCP消息报文。
这篇关于实践:使用socket实现跨进程通信(C语言)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享