一种跨设备实现多进程间通信的方法!
时间:2023-06-22 00:20:17来源:面包芯语

设计思路:

(1)协议选择

由于Unix Domain传输速率大消耗资源少,但它只适用于本地之间传输,AF_INET Domain 消耗资源多,传输相对速率较低。为了高效实现跨设备多进程间通讯,可以同时使用Unix Domain 和 AF_INET Domain进程系统进程间通信。本地进程使用Unix Domain传输,远程设备使用AF_INET传输,为保证命令消息的可靠发送和接收,可以选择TCP传输。

(2)多进程间通信实现

要现实某个进程往其他任意一个进程间发送数据,中间必须建立一个服务端,服务端用来做数据路由,用来减少网络端口的连接同时简化各进程间数据的接收和发送。另外还可以通过路由实现广播的功能。


(资料图片)

(3)命令消息格式设计

在实际应用中,多进程间的通信一般是用来实现各进程间的命令消息交互,为了保证命令消息的正确和完整,一般会对命令消息进行封装,这样也方便接收端在接收到数据的时候进行命令的解析。该命令消息的格式可以定义如下:

基本的通信网络模型如下:

功能实现:

(1)服务端(Router)

对于TCP连接,可以通过IP和端口来确定绑定地址,对于Unix Domain客户端,可以通过路径名来绑定地址。地址定义和绑定如下,这里预定义了20本地进程(客户端),两个远程设备,每个设备10个进程(客户端):

/*************************************************************Copyright (C),lcb0281at163.com lcb0281atgmail.com*FileName: ipc_common.h*BlogAddr: https://blog.csdn.net/li_wen01*Description: socket进程间通信数据结构及参数定义包括跨设备间TCP进程间通信和本地Unix Domain Socket进程间通信*Date:   2019-08-03*Author:   Caibiao Lee*Version:  V1.0*Others:*History:***********************************************************/#ifndef _IPC_COMMON_H_#define _IPC_COMMON_H_/**跨设备TCP socket进程间通信**/#define MAX_EXTARN_DEV_NUM  2      /**最大连接的网络设备数**/#define EACH_TCP_DEV_MAX_CLIENT_NUM   10     /**每个外接网络设备客户端数**/#define TCP_SERVER_PORT  6666   /**TCP连接服务端IP端口**//**TCP连接最大支持客户端数**/#define TCP_SERVER_LISTEN_MAX_NUM ((MAX_EXTARN_DEV_NUM)*(EACH_TCP_DEV_MAX_CLIENT_NUM))#define TCP_SERVER_IP"192.168.1.111"#define TCP_CLIENT_DEVICE1_IP"192.168.1.111"  /**网络设备1 IP地址**/#define TCP_CLIENT_DEVICE2_IP"192.168.1.112"  /**网络设备2 IP地址**/#define TCP_CLIENT_DEVICE1_NO1#define TCP_CLIENT_DEVICE2_NO2/**网络设备各客户端TCP端口**/#define TCP_DEVICE_CLIENT0_POART9000#define TCP_DEVICE_CLIENT1_POART9001#define TCP_DEVICE_CLIENT2_POART9002#define TCP_DEVICE_CLIENT3_POART9003#define TCP_DEVICE_CLIENT4_POART9004#define TCP_DEVICE_CLIENT5_POART9005#define TCP_DEVICE_CLIENT6_POART9006#define TCP_DEVICE_CLIENT7_POART9007#define TCP_DEVICE_CLIENT8_POART9008#define TCP_DEVICE_CLIENT9_POART9009#define TCP_DEVICE_CLIENT_MAX_POART 9009/**本地Unix Domain Socket进程间通信**/#define MAX_UDS_CLIENT_NUM  20        /**最大socket域客户端数,对应最大本地通讯进程数**/#defineSERVER_PATH"../tmp/server_socket"   /**socket域服务端文件**/#define CLIENT_PACHT    "../tmp/client_socket"   /**socket域客户端文件前缀**//**本地客户端模块序号定义**/#define CLIENT_MIN_ADDR1#define LOCAL_CLIENT_1_ADDR        1#define LOCAL_CLIENT_2_ADDR        2#define LOCAL_CLIENT_3_ADDR        3#define LOCAL_CLIENT_4_ADDR        4#define LOCAL_CLIENT_5_ADDR        5#define LOCAL_CLIENT_6_ADDR        6#define LOCAL_CLIENT_7_ADDR        7#define LOCAL_CLIENT_8_ADDR        8#define LOCAL_CLIENT_9_ADDR        9#define LOCAL_CLIENT_10_ADDR        10#define LOCAL_CLIENT_11_ADDR        11#define LOCAL_CLIENT_12_ADDR        12#define LOCAL_CLIENT_13_ADDR        13#define LOCAL_CLIENT_14_ADDR        14#define LOCAL_CLIENT_15_ADDR        15#define LOCAL_CLIENT_16_ADDR        16#define LOCAL_CLIENT_17_ADDR        17#define LOCAL_CLIENT_18_ADDR        18#define LOCAL_CLIENT_19_ADDR        19#define LOCAL_CLIENT_MAX_ADDR        19/**网络设备1客户端模块序号定义**/#define DEV_CLIENT_MIN_ADDR        20#define DEV1_CLIENT_0_ADDR        20#define DEV1_CLIENT_1_ADDR        21#define DEV1_CLIENT_2_ADDR        22#define DEV1_CLIENT_3_ADDR        23#define DEV1_CLIENT_4_ADDR        24#define DEV1_CLIENT_5_ADDR        25#define DEV1_CLIENT_6_ADDR        26#define DEV1_CLIENT_7_ADDR        27#define DEV1_CLIENT_8_ADDR        28#define DEV1_CLIENT_9_ADDR        29/**网络设备1客户端模块序号定义**/#define DEV2_CLIENT_0_ADDR        30#define DEV2_CLIENT_1_ADDR        31#define DEV2_CLIENT_2_ADDR        32#define DEV2_CLIENT_3_ADDR        33#define DEV2_CLIENT_4_ADDR        34#define DEV2_CLIENT_5_ADDR        35#define DEV2_CLIENT_6_ADDR        36#define DEV2_CLIENT_7_ADDR        37#define DEV2_CLIENT_8_ADDR        38#define DEV2_CLIENT_9_ADDR        39#define DEV_CLIENT_MAX_ADDR        39#define CLIENT_MAX_ADDR      39extern const char * gc_au8DeviceNoMap[MAX_EXTARN_DEV_NUM]; extern const unsigned int gc_as32DeviceModuleMap[TCP_SERVER_LISTEN_MAX_NUM][3];

服务端server.c实现代码比较长,这里就不贴出来了,有兴趣的可以到我GitHub上查看:https://github.com/licaibiao/IPC_Socket

(2)客户端(各进程)

为方便客户端对消息命令的处理,客户端设计成每次接收到的数据是一个完整的命令消息,并且只有一条命令消息。为方便客户端的使用,将客户端的网络连接和网络状态检测同时封装到客户端数据接收和数据发送两个接口里面。比如在数据发送的时候,会去判断连接是否建立获取连接已经断开,如果网络异常则重新建立连接。

客户端ipc_interface.h接口定义如下

/*************************************************************Copyright (C),lcb0281at163.com lcb0281atgmail.com*FileName: ipc_interface.c*BlogAddr: https://blog.csdn.net/li_wen01*Description:客户端网络连接,数据收发,消息解析函数接口定义实现*Date:   2019-08-03*Author:   Caibiao Lee*Version:  V1.0*Others:*History:***********************************************************/#ifndef _IPC_INTERFACE_H_#define _IPC_INTERFACE_H_#include "ipc_common.h"#include "ipc_msgstruct.h"/**获取流水号**/int IPCP_Arch_Msg_AnalyzeGetFlowNum();/**获取应答流水号**/int IPCP_Arch_Msg_AnalyzeGetACKResult(ARCH_MSG_S *pstMsg);/**获取流水号地址**/int IPCP_Arch_Msg_AnalyzeGetRecFlow(ARCH_MSG_S *pstMsg);/**获取源地址**/int IPCP_Arch_Msg_ChangeSrcAddr(ARCH_MSG_S *pstMsg,unsigned  char SrcAddr);/**获取目标地址**/int IPCP_Arch_Msg_ChangeTargAddr(ARCH_MSG_S *pstMsg,unsigned  char TargAddr);/**获取源地址**/int IPCP_Arch_Msg_AnalyzeGetSrcAddr(ARCH_MSG_S *pstMsg);/**获取目标地址**/int IPCP_Arch_Msg_AnalyzeGetTargAddr(ARCH_MSG_S *pstMsg);/**获取消息ID**/int IPCP_Arch_Msg_AnalyzeGetCmdID(ARCH_MSG_S *pstMsg);/**获取内容长度**/int IPCP_Arch_Msg_AnalyzeGetLen(ARCH_MSG_S *pstMsg);/**获取消息内容开始位置**/void IPCP_Arch_Msg_PlatformStartP(unsigned char ** p, unsigned char* Data);/**发送数据**/int IPCP_Arch_Msg_PackSend(int s32ModuleAddr, MSG_PACK_S *pstMsg);/**读取数据**/int  IPCP_Arch_Msg_Recv(int s32ModuleAddr,ARCH_MSG_S *pstMsg);#endif

(3)命令消息封装

为了更好地发送和接收命令消息,应该将命令消息基于网络传输协议之上再进行一层消息的封装,添加消息头标签,源地址目的地址和校验等信息。为了各进程间消息的更好识别和传输,应该对每条命令的数据结构进行定义,这样在解析的时候才不会出现参数对应不上的问题。我这里预定义了几个命令消息,用来测试该方法的稳定性。

ipc_msgstruct.h/*************************************************************Copyright (C),lcb0281at163.com lcb0281atgmail.com*FileName: ipc_msgstruct.h*BlogAddr: https://blog.csdn.net/li_wen01*Description:命令消息结构体定义和解析*Date:   2019-08-03*Author:   Caibiao Lee*Version:  V1.0*Others:*History:***********************************************************/#ifndef _IPC_MSGSTRUCT_H_#define _IPC_MSGSTRUCT_H_/**数据结构重定义**/typedef unsigned char    byte;typedef signed char     INT8S;typedef signed int     INT32S;typedef unsigned char    BYTE;typedef unsigned short   WORD;typedef unsigned int     DWORD;typedef unsigned char    INT8U;typedef unsigned short INT16U;typedef unsigned int     INT32U;#define IPCP_TRUE 0#define IPCP_FALSE1#define ARRAY_SIZE(_A) (sizeof(_A) / sizeof((_A)[0]))/**通讯协议位定义**//************************************************************************************//** | 2Byet| Byet | Byet   | 2Byet  | 2*Byet |2Byet    |N*Byet | Byet | 2Byet  | **//** | 0xa5a5 | 源地址| 目标地址| 流水号 | 消息ID |消息长度 |消息体 | 校验 | 0x5a5a | **//** | 0  1   |   2   |    3    |  4  5  |  6  7  | 8  9    |10   | 10+N | 10+N+1 | **//************************************************************************************/#define MSG_SRC_ADDR (2)#define MSG_TAR_ADDR (3)#define MSG_SERIAL_NUM_ADDR (4)#define MSG_CMID_ADDR (6)#define MSG_MSG_LEN_ADDR (8)#define MSG_ACK_CMID_ADDR (10)#define MSG_ACK_SERIAL_NUM_ADDR (12)#define MSG_ACK_RES_ADDR (14)#define MSG_CONTENT_OFFSET  (10)    /**消息内容开始位置**/#define MSG_HEAD_LEN (10)#define MSG_END_LEN  (3)#define MSG_ARCH_MSG_LEN  (13)#define QUEUE_MSG_HEAD              0xa5a5#define QUEUE_MSG_END               0x5a5atypedef struct MsgPack{    unsigned char SrcAddr;    unsigned char TargAddr;    unsigned short Len;    unsigned char *Data;    unsigned short CmdId;}MSG_PACK_S;#define  MSG_TEXT_SIZE       (2048)typedef struct ARCH_MSG{    unsigned int MsgLen;               unsigned char SomeText[MSG_TEXT_SIZE];}ARCH_MSG_S;/*通用IPCP指令*/#define QUEUE_DEBUG_CMD1        (0x0001)#define QUEUE_DEBUG_CMD2        (0x0002)#define QUEUE_DEBUG_CMD3        (0x0003)#define QUEUE_DEBUG_CMD4        (0x0004)#define QUEUE_DEBUG_CMD5        (0x0005)#define QUEUE_DEBUG_CMD6        (0x0006)#define QUEUE_DEBUG_CMD7        (0x0007)#define QUEUE_DEBUG_CMD8        (0x0008)#define QUEUE_DEBUG_CMD9        (0x0009)#define QUEUE_DEBUG_CMDA        (0x000A)#define QUEUE_DEBUG_MAX_CMD (0x000A)/**消息定义**/typedef struct{DWORD   u32Alarm;         /* 报警 */DWORD u32Status;        /* 状态 */DWORD u32Latitude;      /* 纬度,百万分之一度 */  DWORD u32Longtitude;    /* 经度,百万分之一度 */  WORDu16Altitude;   /* 高程,米 */WORDu16SpeedX10;      /* gps速度,1/10 km/h */WORD  u16Direct;        /* 方向 */ BYTE    arrCardNo[16];       /* 机动车牌号码 */WORD    u16SensorSpeed;        /* 脉冲速度,1/10 km/h */BYTE    u8CarCor;   /* 车牌颜色  */}__attribute__ ((__packed__))MSG_0X0001_S;typedef struct{unsigned int  u32FileId;    /**文件id,不为0时,按文件id查找**/ unsigned char u8DeleteFlag;/**删除标志:0:保留;1:删除**/ unsigned char u8StopFlag;/**停止上传标志:0:保留;1:停止上传**/ unsigned char u8srcPlat;    /**下发命令的平台地址**/}__attribute__ ((__packed__))MSG_0X0002_S;typedef struct{unsigned char u8Type;     /**0人脸识别结果,1人头个数识别**/ unsigned char u8Result;          /**type为0时,0成功,1失败**/ }__attribute__ ((__packed__))MSG_0X0003_S;typedef struct{unsigned char u8Interval;/**时间间隔**/ unsigned int  u32Duration;    /**持续时间**/ }__attribute__ ((__packed__))MSG_0X0004_S;typedef struct{    DWORD u32MultiId;/**多媒体ID,小端内存**/   WORD  u16TotalNum;/**下发拍照的总数**/    WORD  u16CurNum;/**当前图片序号**/ BYTE  u8PlatAddr;/**平台地址**/}__attribute__ ((__packed__))MSG_0X0005_S;typedef struct{DWORD   u32ModeEvent;      /**休眠唤醒事件:1:休眠,2:唤醒*/}__attribute__ ((__packed__))MSG_0X0006_S;typedef struct{DWORD    u32ParaId;      /* 参数id: 0x1000010C*/BYTE     u8ParaLen;   /* 参数长度: 4 */unsigned long long u64AlarmFlag;/* bit*/}__attribute__ ((__packed__))MSG_0X0007_S;typedef struct{DWORD    u32ParaId;     /* 参数id: 0x1000010C*/BYTE     u8ParaLen;  /* 参数长度: 4 */DWORD    u32TimeOut;  /* 单位为秒*/}__attribute__ ((__packed__))MSG_0X0008_S;typedef struct{DWORD    u32ParaId;     /* 参数id: 0x30000007*/BYTE     u8ParaLen;  /* 参数长度: 4 */DWORD    u32Payload;  /* 参数值:96:h264编码, 265:h265编码*/}__attribute__ ((__packed__))MSG_0X0009_S;typedef struct{BYTEu8ParaNum;            /* 参数总数 */}__attribute__ ((__packed__))MSG_0X000A_S;typedef int (*HandleHook_Func)(unsigned char*, unsigned short,unsigned char);typedef struct {    unsigned int u32MsgID;    HandleHook_Func pFuncHandle;}MSG_HANDLE_HOOK_S;int IPCPMsg_Debug_Cmd1(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd2(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd3(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd4(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd5(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd6(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd7(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd8(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_Cmd9(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);int IPCPMsg_Debug_CmdA(unsigned char *pu8SomeText, unsigned short u16Len, unsigned char u8SrcAddr);#endif

测试:

为了测试该方法的可靠和稳定性,有新建2个本地进程和2个远程设备进程,让他们随机时间随机往某个进程发送命令,看是否会出现命令消息丢失或是解析错误的问题。其中本地一个客户端的实现如下:

/*************************************************************Copyright (C),lcb0281at163.com lcb0281atgmail.com*FileName: local_client1.c*BlogAddr: https://blog.csdn.net/li_wen01*Description:本地模块进程1*Date:   2019-08-03*Author:   Caibiao Lee*Version:  V1.0*Others:*History:***********************************************************/#include #include #include #include #include #include #include #include "ipc_interface.h"#include "ipc_msgstruct.h"#include "ipc_common.h"#define CLIENT_MODULE_ADDR   LOCAL_CLIENT_1_ADDR#define LOCAL1_DELAY_FOR_DEBUG_US  (1000*1000)/**消息处理**/MSG_HANDLE_HOOK_S g_astLocalMsgTable[] ={{QUEUE_DEBUG_CMD1, IPCPMsg_Debug_Cmd1},{QUEUE_DEBUG_CMD2, IPCPMsg_Debug_Cmd2},{QUEUE_DEBUG_CMD3, IPCPMsg_Debug_Cmd3},{QUEUE_DEBUG_CMD4, IPCPMsg_Debug_Cmd4},{QUEUE_DEBUG_CMD5, IPCPMsg_Debug_Cmd5},{QUEUE_DEBUG_CMD6, IPCPMsg_Debug_Cmd6},{QUEUE_DEBUG_CMD7, IPCPMsg_Debug_Cmd7},{QUEUE_DEBUG_CMD8, IPCPMsg_Debug_Cmd8},{QUEUE_DEBUG_CMD9, IPCPMsg_Debug_Cmd9},{QUEUE_DEBUG_CMDA, IPCPMsg_Debug_CmdA},    {0,NULL},};/**********************************linux ctrl + C 会产生 SIGINT信号接收到SIGINT 信号进入该函数**********************************/void stop(int signo){int i = 0;printf(" stop \n");_exit(0);}/*********************************************当客户端断开连接的时候,在服务端socket send进程可以收到收到信号SIGPIPE,收到SIGPIPE信号进入该函数结束创建的线程。**********************************************/void signal_pipe(int signo){}/******************************************************** Function: ClientSendMsg  Description: 客户端(某一进程)发送数据包Input:s32TargModuleAddr : 需要发送到的模块地址OutPut: noneReturn: 0 成功;非0 异常Others:Author: Caibiao LeeDate:2019-08-03*********************************************************/int ClientSendMsg(int s32TargModuleAddr){int l_s32Res = 0;MSG_PACK_S l_stMsg = {0};MSG_0X0001_S l_stMsgSend = {0};if((s32TargModuleAddrLOCAL_CLIENT_MAX_ADDR)){printf("%s %d input para error %d \n",__FUNCTION__,__LINE__,s32TargModuleAddr);return -1;}l_stMsgSend.arrCardNo;l_stMsgSend.u16Altitude   = 0x66;l_stMsgSend.u16Direct     = 0x11;l_stMsgSend.u16SensorSpeed= 0x12;l_stMsgSend.u16SpeedX10   = 0x13;l_stMsgSend.u32Alarm      = 0xbb;l_stMsgSend.u32Latitude   = 0xaa;l_stMsgSend.u32Longtitude = 0x15;l_stMsgSend.u32Status     = 0x01;l_stMsgSend.u8CarCor  = 0x08;l_stMsg.CmdId    = QUEUE_DEBUG_CMD1;l_stMsg.Data     = (unsigned char*)&l_stMsgSend;l_stMsg.Len      = sizeof(MSG_0X0001_S);l_stMsg.SrcAddr  = CLIENT_MODULE_ADDR;l_stMsg.TargAddr = s32TargModuleAddr;IPCP_Arch_Msg_PackSend(CLIENT_MODULE_ADDR,&l_stMsg);return 0;}/******************************************************** Function: ClientRecvMsg  Description: 客户端(某一进程)接收数据包,并对数据包进行解析Input:OutPut: noneReturn: 0 成功;非0 异常Others:Author: Caibiao LeeDate:2019-08-03*********************************************************/int ClientRecvMsg(void){int i = 0;int l_s32RecvLen = 0;int l_s32SrcAddr = 0;int l_s32CmdId   = 0;int l_s32TextLen = 0;int l_s32FlowNum = 0;int l_u32IPCPMsgNum = 0;unsigned char *l_pu8MsgBody = NULL;ARCH_MSG_S l_stMsg = {0};l_s32RecvLen = IPCP_Arch_Msg_Recv(CLIENT_MODULE_ADDR,&l_stMsg);if(l_s32RecvLen>0){IPCP_Arch_Msg_PlatformStartP(&l_pu8MsgBody, l_stMsg.SomeText);l_u32IPCPMsgNum = ARRAY_SIZE(g_astLocalMsgTable);l_s32SrcAddr = IPCP_Arch_Msg_AnalyzeGetSrcAddr(&l_stMsg);l_s32CmdId   = IPCP_Arch_Msg_AnalyzeGetCmdID(&l_stMsg);l_s32TextLen = IPCP_Arch_Msg_AnalyzeGetLen(&l_stMsg);l_s32FlowNum = IPCP_Arch_Msg_AnalyzeGetRecFlow(&l_stMsg);printf("l_s32SrcAddr = %d \n",l_s32SrcAddr);printf("l_s32CmdId   = %d \n",l_s32CmdId);printf("l_s32TextLen = %d \n",l_s32TextLen);printf("l_s32FlowNum = %d \n",l_s32FlowNum);for(i = 0; i < l_u32IPCPMsgNum; i++){if(l_s32CmdId == g_astLocalMsgTable[i].u32MsgID){if(NULL!=g_astLocalMsgTable[i].pFuncHandle){g_astLocalMsgTable[i].pFuncHandle(l_pu8MsgBody, l_s32TextLen,l_s32SrcAddr);}break;}}}return 0;}int main(int argc,char *argv[]){int l_s32Delay    = 0;int l_s32Addr     = 0;int l_as32SendAddr[3] ={0};l_as32SendAddr[0] = LOCAL_CLIENT_2_ADDR;l_as32SendAddr[1] = DEV1_CLIENT_1_ADDR,l_as32SendAddr[2] = DEV1_CLIENT_2_ADDR;/**注册 SIGPIPE信号**/signal(SIGPIPE,signal_pipe); /**注册SIGINT 信号**/signal(SIGINT,stop); while(1){l_s32Addr = IPCP_GetRandomReal(0,3);if((l_s32Addr>=0)&&(l_s32Addr<=2)){ClientSendMsg(l_as32SendAddr[l_s32Addr]);}ClientRecvMsg();l_s32Delay = IPCP_GetRandomReal(50,100);usleep(l_s32Delay*1000);}return 0;}

实际运行结果如下:

上面测试是以50~100ms随机发送一包数据来测试,运行24小时后未检测到异常。

总结:

(1)阻塞与非阻塞问题

实际客户端在接收和发送,应该是需要非阻塞的模式,正常的数据接收和发送不能影响客户端原本的业务逻辑处理。在非阻塞状态下数据的接收和发送都需要特别的注意。

在发送的时候,因为是非阻塞的,当对方接收缓存满了的时候,发送端会收到EAGAIN的错误码,该错误码是让你进行数据的重新发送。在我这里我是设计发送失败会重新发送3遍,然后3次发送后还是失败,那么这包数据就会被丢弃。

在接收的时候,我们需要去判断对方网络是否还处于连接的状态,可以使用select实现,也可以通过接收PIPE信号来判断,为了更好的数据处理,在我这里是使用select来判断对方网络是否已经断开连接。

(2)缓存大小问题

每建立一个socket,在连接或是绑定之前,我们都可以设置该socket连接的收发缓存大小,可以根据实际应用的发送峰值来判断应该设置多大的缓存。在我Ubuntu16.04系统下,默认的TCP和UnixDomain收发缓存大小如下:

biao@ubuntu:~/test/ipcp_socket/server$ ./servercreate unix domin socket lpthread successcreate TCP socket lpthread successcreate read write lpthread seccessTCP SO_RCVBUF = 87380TCP SO_SNDBUF = 16384server waiting for tcp client connectUnix Domain SO_RCVBUF = 212992Unix Domain SO_SNDBUF = 212992server waiting for unix domain client connect

工程下载:

以上,完整代码文件如下:

biao@ubuntu:~/test/ipcp_socket$ tree.├── common│ ├── ipc_common.c│ ├── ipc_common.h│ ├── ipc_interface.c│ ├── ipc_interface.h│ ├── ipc_msgstruct.c│ └── ipc_msgstruct.h├── device1│ ├── device1_client1.c│ ├── device1_client2.c│ └── Makefile├── local│ ├── local_client1.c│ ├── local_client2.c│ └── Makefile├── server│ ├── Makefile│ └── server.c└── tmp    ├── client_socket1    ├── client_socket2    └── server_socket5 directories, 17 filesbiao@ubuntu:~/test/ipcp_socket$

liwen01公众号中回复 网络编程获取工程代码,本章代码工程名为:ipcp_socket_20190815_V2.tar.gz

本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

注意

猜你喜欢:

谈谈嵌入式软件的兼容性!

我是韦东山老师的忠实粉丝!

标签:

  • 上一篇文章: 天天观天下!夏至前的田野
  • 下一篇文章: 最后一页
  • 生活指南
  • 肯德基全家桶多少钱一桶2023年?正版adobe全家桶多少钱? 焦点快看

    肯德基全家桶多少钱一桶2023年? 黄金脆皮鸡新春桶 108元 桶(香辣鸡

  • 有志难伸_对于有志难伸简单介绍-每日精选

    1、汉语成语,拼音是yǒuzhìnánshēn,意思是有远大抱负而难以施展。

  • 环球快播:鞍山师范学院录取查询系统2021_鞍山师范学院录取查询

    1、现在应该是已经发了,就在邮局的路上。2、你登陆学校招生办的网站,

  • 北京的演唱会一般在哪里举行?2023年北京的演唱会有哪些? 今日精选

    北京的演唱会一般在哪里举行?大型演唱会常用举办场地:凯迪拉克中心

  • 常见的电子邮箱有哪些?yy直播间怎么赚钱? 最新资讯

    常见的电子邮箱有哪些在网络中,电子邮箱可以自动接收网络任何电子

  • 价值投资的核心内容是什么?价值投资和成长投资的不同点

    最近小编看到很多人在搜索价值投资的相关内容,小编呢对此也是非常

  • 欧洲冠军联赛奖金是多少欧元?中国足球在欧洲比赛是什么水平?

    欧洲冠军联赛奖金是多少欧元?欧洲冠军联赛奖金因赛季不同而有所变化

  • 天天看点:新三板到主板要多久?新三板转主板需要哪些条件?

    企业需要选择适合自己的上市板块。对于一些小型企业来说,新三板是

  • 全球微动态丨【甘快看】短视频制作、直播带货免费培训来袭,你务必要来!

    您是否想搭上直播带货的快车? 您是否摄制的短视频播放量不高? 您是

  • 欠网商贷了5万三年没还支付宝不显示怎么办?支付宝收款后会不会冻结?

    在现代社会,贷款已经成为了人们生活中不可或缺的一部分。但是,如果贷

  • 世界热文:沙滩地适合种什么 沙滩地适合种哪些植物

    1、种植杨树。杨树的生长速度较快,根系发达,在土质疏松的地方生长快

  • 天天快看:快讯!俄媒:普京称,乌军试图发动反攻,但没有反攻机会

    【环球网快讯】据俄新社报道,俄罗斯总统普京16日出席圣彼得堡国际经济

  • 每日快报!挖机开进门面房,打通多间墙体还下挖地面!被叫停后竟再次开工!

    日前,有连云港观众反映说,小区一楼多间门面房被产权人出租后,承租人

  • 今日纸白银价格行情(2023年6月16日)

    今日纸白银价格行情(2023年6月16日)

  • 王姬别动我抽屉_别动我抽屉-每日热讯

    1、是电影东北恋歌。2、包贝尔原名艾志超,出生于黑龙江哈尔滨市,毕业

  • 青海油田68年累计生产油气当量超过1.5亿吨 当前快看

    中新网西宁6月16日电(暴海宏段国东李江宁)据中国石油天然气集团公司青

  • 民生
    • 哈尔滨毕业生户口迁移

    • 火电核电重启电不荒,加码绿能奔向碳中和_天天快讯

    • 宝龙地产正就美国境外非美国人士所持交换票据进行交换要约-快资讯

    • 折价率和溢价率是什么?折价大宗交易是利好还是利空? 环球滚动