ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

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

2021-09-19 22:34:27  阅读:127  来源: 互联网

标签:addr ERR SOCK 实践 ret C语言 pPara socket


功能描述

使用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(&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;
}

功能演示

  • 第一步:打开Linux操作窗口,启动Server进程。
./test_socket server 127.0.0.1 1500

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


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

标签:addr,ERR,SOCK,实践,ret,C语言,pPara,socket
来源: https://www.cnblogs.com/kunlingou/p/15312985.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有