linux:socket本地通信

File : socket.c (直接右键另存为下载)
Type : linux
Brief : 使用socket的UNIX域实现本地通信


#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include <pthread.h>
#include <error.h>
#include <stddef.h>

int server_start_tcp(const char* name, int size)
{
    int sfd, cfd, len;
    struct sockaddr_un un;

    /* create server socket of unix */
    if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        return -1;

    /* set listen address */
    unlink(name); /* in case it already exists*/
    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    memcpy(un.sun_path, name, size);
    len = offsetof(struct sockaddr_un, sun_path) + size;

    /* bind to address */
    if (bind(sfd, (struct sockaddr*)&un, len) < 0)
    {
        close(sfd);
        return -2;
    }

    /* listen to sfd */
    if (listen(sfd, 10) < 0)
    {
        close(sfd);
        return -3;
    }

    /* accept client connection */
    len = sizeof(un);
    if ((cfd = accept(sfd, (struct sockaddr*)&un, &len)) < 0)
        return -1;

    const char* str = "Hello monday.\0";
    char        buf[1024];
    int         res, cnt = 0;

    while (1)
    {
        cnt ++;
        printf("%3d-th loop\n\t", cnt);

        res = read(cfd, buf, sizeof(buf));
        for (int k = 0; k < res; k ++)
            printf("%c", buf[k]);
        printf("\n\t");

        res = write(cfd, str, strlen(str));
        for (int k = 0; k < res; k ++)
            printf("%c", str[k]);
        printf("\n");

        sleep(1);
    }

    close(sfd);
    return 0;
}

int server_udp(const char* name, int size)
{
    int fd, len;
    struct sockaddr_un un;

    /* create server socket of unix */
    if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
        return -1;

    unlink(name);
    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    memcpy(un.sun_path, name, size);
    len = offsetof(struct sockaddr_un, sun_path) + size;

    /* bind to address */
    if (bind(fd, (struct sockaddr*)&un, len) < 0)
    {
        close(fd);
        return -2;
    }

    const char* str = "Hello monday.\0";
    char        buf[1024];
    int         res, cnt = 0;

    while (1)
    {
        cnt ++;
        printf("%3d-th loop\n\t", cnt);


        res = recvfrom(fd, buf, sizeof(buf), 0, (const struct sockaddr*)&un, &len);
        for (int k = 0; k < res; k ++)
            printf("%c", buf[k]);
        printf("\n\t");

        /*res = sendto(fd, str, strlen(str), 0, (const struct sockaddr*)&un, len);*/
        /*for (int k = 0; k < res; k ++)                                          */
        /*    printf("%c", str[k]);                                               */
        /*printf("\n");                                                           */

        sleep(1);
    }

    close(fd);
    return 0;
}

int client_connect_tcp(const char* name, int size)
{
    int cfd, len;
    struct sockaddr_un un;

    /* create client socket of unix */
    if ((cfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        return -1;

    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    memcpy(un.sun_path, name, size);
    len = offsetof(struct sockaddr_un, sun_path) + size;

    /* connect to server socket */
    if (connect(cfd, (struct sockaddr*)&un, len) < 0)
    {
        close(cfd);
        return -2;
    }

    const char* str = "Hello sunday.\0";
    char        buf[1024];
    int         res, cnt = 0;

    while(1)
    {
        cnt ++;
        printf("%3d-th loop\n\t", cnt);

        res = write(cfd, str, strlen(str));
        for (int k = 0; k < res; k ++)
            printf("%c", str[k]);
        printf("\n\t");

        res = read(cfd, buf, sizeof(buf));
        for (int k = 0; k < res; k ++)
            printf("%c", buf[k]);
        printf("\n");

        sleep(1);
    }

    close(cfd);
    return 0;
}

int client_udp(const char* name, int size)
{
    int fd, len;
    struct sockaddr_un un;

    /* create client socket of unix */
    if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
        return -1;

    unlink(name);
    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    memcpy(un.sun_path, name, size);
    len = offsetof(struct sockaddr_un, sun_path) + size;

    const char* str = "Hello monday.\0";
    char        buf[1024];
    int         res, cnt = 0;

    while (1)
    {
        cnt ++;
        printf("%3d-th loop\n\t", cnt);

        res = sendto(fd, str, strlen(str), 0, (const struct sockaddr*)&un, len);
        for (int k = 0; k < res; k ++)
            printf("%c", str[k]);
        printf("\n\t");

        /*res = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);*/
        /*for (int k = 0; k < res; k ++)                      */
        /*    printf("%c", buf[k]);                           */
        /*printf("\n");                                       */

        sleep(1);
    }

    close(fd);
    return 0;
}

int main()
{
    // 使用 netstat -an 命令可以看到name
    //const char* name = "foo.socket";            /* 普通名字空间 */
    const char* name = "\0foo.socket";          /* 虚拟名字空间 */
    int size = strlen(&name[1]) + 1;

#if 0
    #if 1
        int ret = server_start_tcp(name, size);
        printf("%d", ret);
    #else
        int ret = client_connect_tcp(name, size);
        printf("%d", ret);
    #endif
#else
    #if 1
        int ret = server_udp(name, size);
        printf("%d", ret);
    #else
        int ret = client_udp(name, size);
        printf("%d", ret);
    #endif
#endif
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [ yehuohan@gmail.com ]

文章标题:linux:socket本地通信

本文作者:Y

发布时间:2019-04-11, 14:59:18

最后更新:2019-05-21, 20:08:13

原始链接:http://yehuohan.github.io/2019/04/11/Gist/linux/linux-socket%E6%9C%AC%E5%9C%B0%E9%80%9A%E4%BF%A1/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。