zoukankan      html  css  js  c++  java
  • 实践:使用socket实现跨进程通信(C语言)

    实践:使用socket实现跨进程通信(C语言)

    材料归档

    功能描述

    使用socket通信,实现服务端功能和客户端功能,并进行消息的交互,实现跨进程通信。

    功能演示

    第一步:打开Linux操作窗口,启动Server进程。

    ./test_socket server 127.0.0.1 1500
    

    第二步:打开另一个Linux操作窗口,启动Client进程。可以观察到Client收到Server的消息,同时观察Server日志可以发现发送成功。

    ./test_socket client 127.0.0.1 1500
    


    第三步:查看抓包。可以看到对应的TCP消息报文。

    相关代码

    test_socket.h

    #ifndef __TEST_SOCKET_H__
    #define __TEST_SOCKET_H__
    
    #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_ERR(fmt...) do { 
        printf("[SOCK]" fmt);     
        printf("
    ");           
    } while(0)
    
    #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 sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1) {
            SOCK_ERR("socket Fail!");
            return VOS_ERR;
        }
        SOCK_ERR("socket(%d) create ok", sock);
    
        // bind
    
        SOCK_ADDR_S addr;
        addr.family                      = AF_INET;
        addr.port                        = htons(pPara->port);
        addr.addr                        = inet_addr(pPara->addr);
    
        ret = bind(sock, (struct sockaddr *)&addr, sizeof(SOCK_ADDR_S));
        if (ret < 0) {
            SOCK_ERR("socket bind Err(%d)!", ret);
            return VOS_ERR;
        }
    
        // listen
    
        ret = listen(sock, 5);
        if (ret != VOS_OK) {
            SOCK_ERR("socket listen Err(%d)!", ret);
            return VOS_ERR;
        }
    
        SOCK_ERR("socket accept ...");
    
        // accept
    
        INT32       clientSock;
        SOCK_ADDR_S clientAddr;
        UINT32      clientAddrLen        = sizeof(SOCK_ADDR_S); // 注意:这里得是有效值
    
        while (VOS_TRUE) {
            clientSock = accept(sock, (struct sockaddr *)&clientAddr, &clientAddrLen);
            if (clientSock == -1) {
                SOCK_ERR("socket accept Fail(%d)", clientSock);
            } else {
                SOCK_ERR("socket accept Succ");
                ret = send(clientSock, "Hello World!", 12, 0);
                if (ret == -1) {
                    SOCK_ERR("socket send Fail");
                } else {
                    SOCK_ERR("socket send Succ");
                }
            }
        }
    
        return VOS_OK;
    }
    
    UINT32 SOCK_MainClient(SOCK_PARA_S *pPara)
    {
        INT32 ret;
    
        // socket
    
        INT32 sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1) {
            SOCK_ERR("socket Fail!");
            return VOS_ERR;
        }
        SOCK_ERR("socket(%d) create ok", sock);
    
        // connet
    
        SOCK_ADDR_S addr;
        addr.family                      = AF_INET;
        addr.port                        = htons(pPara->port);
        addr.addr                        = inet_addr(pPara->addr);
    
        ret = connect(sock, (struct sockaddr *)&addr, sizeof(SOCK_ADDR_S));
        if (ret == -1) {
            SOCK_ERR("socket connet Fail(%d)!", ret);
            return VOS_ERR;
        }
    
        // recv
    
        char buf[100] = {0};
    
        ret = recv(sock, buf, 100, 0);
        if (ret == -1) {
            SOCK_ERR("socket recv Fail(%d)!", ret);
            return VOS_ERR;
        }
        SOCK_ERR("socket recv Succ(%s)!", buf);
    
        return VOS_ERR;
    }
    
    int main(int argc, char *argv[])
    {
        SOCK_PARA_S para;
        SOCK_InitPara(&para, argc, argv);
    
        SOCK_ERR("test socket start");
    
        if (para.type == SOCK_PROCESS_TYPE_SERVER) {
            (VOID)SOCK_MainServer(&para);
        } else {
            (VOID)SOCK_MainClient(&para);
        }
    
        SOCK_ERR("test socket end");
    
        return VOS_OK;
    }
    
    剑指 Offer
  • 相关阅读:
    Service Workers里的CacheStorage和Cache
    application cache和localstorage的区别
    localStorage和sessionStorage区别
    Ubuntu软件的安装和使用
    C++之数据类型
    C++之C++的词法单位
    C++之语言概述
    Ubuntu双系统无法挂载Windows10 硬盘的解决方法
    opencv 显示摄像头数据
    Ubuntu 中使用git 上传代码
  • 原文地址:https://www.cnblogs.com/kunlingou/p/15312985.html
Copyright © 2011-2022 走看看