`

AF_UNIX实现linux本地socket通信的笔记

 
阅读更多

AF_UNIX与AF_LOCAL是一样的,只是历史遗留原因。

有SOCK_STREAM、SOCK_DGRAM、SOCK_SEQPACKET三种工作模式 

 

1、SOCK_STREAM

流字节套,类似TCP,由于socket发送缓冲区的缘故,多次write数据会被缓冲区整合为一次底层send。禁用TCP Nagle算法的方式对AF_UNIX无效。

 

#include <netinet/in.h> // for IPPROTO_TCP
#include <netinet/tcp.h> // for TCP_NODELAY

int nodelay = 1;
ret = setsockopt(mSocket, IPPROTO_TCP, TCP_NODELAY,(void*)&nodelay,sizeof(nodelay));
if (ret == -1) {
    printf("Couldn't setsockopt(TCP_NODELAY)\n");
}

 

2、SOCK_DGRAM

报文字节套,类似UDP的报文方式,理论上会导致错乱、丢失等风险,只是AF_UNIX性能很高,风险概率较小。SOCK_DGRAM的应用场合很少,因为流式套接字在本地的连接时间可以忽略,而SOCK_DGRAM发送接收都需要携带对方的本地地址,所以效率并没有提高。

 

 

3、SOCK_SEQPACKET

SOCK_SEQPACKET提供一个顺序确定的,可靠的,双向基于连接的socket endpoint. 与SOCK_STREAM不同的是,它保留消息边界。(表明发送两个数据包,只能分两次读入)使用SOCK_SEQPACKET工作模式,就可以保证每次write都会发起底层send。

 

mSocket = socket(AF_UNIX, SOCK_SEQPACKET, 0);

但这样接收端延迟非常严重。 

 

4、设置发送端缓冲区容量

 

        int ret = 0;
        int snd_buf_size = 0;
        socklen_t opt_size = sizeof(snd_buf_size);
        /* 获得sndbuf的长度 */
        ret = getsockopt(mSocket, SOL_SOCKET, SO_SNDBUF, &snd_buf_size, &opt_size);
        printf("====================%d\n", snd_buf_size);

        /* 设置sndbuf的长度 */
        int m = 100; // 无法低于系统默认,比如这里虽然设100,实际最小只能到2048
        setsockopt(mSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&m, sizeof(m));
        if (ret == -1) {
            printf("====================Couldn't setsockopt(SO_SNDBUF)\n");
        }
        ret = getsockopt(mSocket, SOL_SOCKET, SO_SNDBUF, &snd_buf_size, &opt_size);
        printf("====================%d\n", snd_buf_size);

 所以仍然会有多次write一次send的现象。

 

 

5,屏蔽中断

    如server已关闭,client继续write就会导致SIGPIPE中断,从而进程中断。

 

    // 当write已关闭socket时会触发SIGPIPE,需要屏蔽
    sigset_t signal_mask;
    sigemptyset(&signal_mask); /* 初始化信号集,并清除signal_mask中的所有信号 */
    sigaddset(&signal_mask, SIGPIPE); /* 将signo添加到信号集中 */
    sigprocmask(SIG_BLOCK, &signal_mask, NULL); /* 这个进程屏蔽掉signo信号 */

 

 

6,命名socket与非命名socket

    命名socket必须具备“/tmp/xxx”的操作权限,因为会在该路径创建链路文件,直到unlink解除。

 

/* 服务器端 */
int server_len;
sockaddr_un s_un;
s_un.sun_family = AF_UNIX;

strcpy(s_un.sun_path, "/tmp/xxx");
server_len = sizeof(struct sockaddr_un);
bind(mSocket, (sockaddr*)&s_un, server_len);
// 解除旧链路
unlink("/tmp/xxx");

/* 客户端 */
sockaddr_un mSockAddr.sun_family = AF_LOCAL;
strcpy(mSockAddr.sun_path, "/tmp/xxx");
int mSockAddrLen = sizeof(sockaddr_un);
connect(mSocket, (sockaddr*)&mSockAddr, mSockAddrLen);

    而非命名socket没有这个限制,但要求必须以@开头声明链路且s_un.sun_path[0]=0。

 

#include <stddef.h> // for offsetof
#define SERVER_NAME "@socket_server"

/* 服务器端 */
int server_len;
sockaddr_un s_un;
s_un.sun_family = AF_UNIX;
strcpy(s_un.sun_path, SERVER_NAME);
s_un.sun_path[0]=0;
int server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);

bind(mSocket, (sockaddr*)&s_un, server_len);


/* 客户端 */
sockaddr_un mSockAddr.sun_family = AF_LOCAL;
mSockAddr.sun_path[0]=0;
int mSockAddrLen = strlen(SERVER_NAME) + offsetof(struct sockaddr_un, sun_path);

connect(mSocket, (sockaddr*)&mSockAddr, mSockAddrLen);

 

 

 

分享到:
评论

相关推荐

    AF_UNIX域的本地进程通信客户端服务端通信源码

    标题中的“AF_UNIX域的本地进程通信客户端服务端通信源码”指的是在Unix/Linux系统中使用AF_UNIX(也称为AF_LOCAL)套接字协议族进行进程间通信(IPC)的代码实现。这种通信方式适用于同一台机器上的不同进程之间...

    php与C语言通过AF_UNIX来进行IPC通信的例子

    AF_UNIX套接字主要在本地系统中使用,它们不需要网络支持,因此通信速度更快,且不受网络协议的限制。通信双方通过文件描述符(file descriptor)来识别对方,通常是一个隐藏的文件路径。这种方式适用于需要高性能、...

    service_client_socket.rar_linux 服务端_linux下socket_socket_socket通信

    首先,`socket`是Unix和类Unix系统(包括Linux)中的一个API接口,它允许程序员创建网络连接并进行数据传输。在Linux下,Socket通信通常涉及以下步骤: 1. **创建Socket**:使用`socket()`函数创建一个Socket描述符...

    unix,af_unix

    af_unixaf_unixaf_unixaf_unix 使用

    QT_的socket_与_Linux_的socket通信Linux

    以上示例展示了如何使用QT的`QTcpSocket`类和Linux Socket API来实现客户端与服务器之间的通信。通过这种方式,开发人员可以在QT应用程序中充分利用Linux的底层网络功能,从而实现更复杂的应用场景。

    CS.rar_linux cs_unix socket

    该函数需要指定套接字类型和协议族,如AF_UNIX(用于本地通信)或AF_INET(用于网络通信)。 2. **绑定**:使用`bind()`函数将套接字与特定的地址(通常是文件路径或IP地址和端口号)关联起来,这样其他进程就可以...

    socket_test.zip_Linux下的socket_linux socket_linux socket server_l

    使用`socket()`函数创建一个socket,需要指定协议族(如AF_INET代表IPv4)、套接字类型(如SOCK_STREAM代表TCP)和协议(通常是0,系统会自动选择默认的TCP或UDP协议)。 3. **bind函数绑定**: `bind()`函数用于...

    junixsocket:Java中的Unix域套接字(AF_UNIX)

    junixsocket junixsocket是一个Java / JNI库,允许使用Java的(AF_UNIX套接字)。为什么很酷junixsocket是一个小型的模块化库。 仅安装您需要的内容。 与其他实现相反, junixsocket扩展了Java Sockets API( java...

    SOCKET-on-Linux.zip_linux socket_linux socket_linux_socket

    - 使用`socket()`函数创建一个Socket,需要指定协议族(如AF_INET用于IPv4,AF_INET6用于IPv6),套接字类型(如SOCK_STREAM为TCP,SOCK_DGRAM为UDP)以及协议(通常为0,由系统自动选择)。 3. **绑定Socket**: ...

    Linux 本地Socket通讯

    在本地环境中,Socket通讯主要使用AF_UNIX或者PF_UNIX域,也被称为Unix域Socket。这种类型的Socket允许同一主机上的不同进程共享数据,其效率通常比其他IPC机制(如管道、消息队列、共享内存等)更高,因为它们不...

    Linux-socket-TCP-ClientServer.zip_TCP socket_linux socket_linux

    在Linux系统中,TCP(Transmission Control Protocol)套接字是实现客户端与服务器间可靠通信的基础。本教程将探讨如何在Linux环境下使用C语言编写TCP socket的客户端和服务器程序。TCP是一种面向连接的、可靠的传输...

    Linux-socket-serverandclient.rar_embedded_linux server socket_l

    1. 创建套接字:使用`socket()`函数创建一个新的套接字,指定协议类型(如TCP)和地址族(如AF_INET)。 2. 绑定地址:使用`bind()`函数将套接字与特定的IP地址和端口号绑定,以便客户端可以找到服务器。 3. 监听...

    Socket_UDP1.00.rar_Linux下udp协议_UDP socket_linux socket u_socket

    创建一个socket,通常需要调用`socket()`函数,指定协议族(如AF_INET代表IPv4)、套接字类型(SOCK_DGRAM对应UDP)以及协议(通常是0,系统会自动选择UDP)。 接下来,我们关注UDP套接字的使用。与TCP套接字不同,...

    linux_socket_thread.zip_linux 网络通信_linux 网络通信_多线程socket

    在Linux系统中,网络通信是通过套接字(Socket)接口来实现的,这是一种标准的进程间通信(IPC)机制,常用于实现客户端与服务器之间的数据交换。在本压缩包"linux_socket_thread.zip"中,包含的是一个使用C语言编写...

    Linux_CAN编程详解_socketCAN_canbus_linux_linuxcan_

    1. 创建套接字:使用`socket()`函数创建一个CAN套接字,指定地址族为AF_CAN。 2. 绑定套接字:使用`bind()`函数将套接字与CAN接口关联,如`"can0"`。 3. 设置过滤器:使用`setsockopt()`函数设置CAN过滤器,筛选接收...

    C语言实现socket简单通信实例.zip_VC socket实例_socket_socket通信

    在IT行业中,网络通信是计算机科学的一个重要领域,而Socket编程是实现网络通信的基础。本教程将通过一个简单的C语言实现的Socket通信实例,讲解如何在VC++6.0环境下进行Socket编程。这个实例包括了服务端和服务端两...

    好例子网_socketcommunicate_socketcommunicate_socket通信_

    2. **创建Socket**:调用`socket()`函数创建一个socket描述符,指定协议类型(如TCP或UDP)和地址族(通常为AF_INET,表示IPv4)。 3. **配置Socket**:对于服务器端,需要调用`bind()`函数将socket绑定到特定的IP...

    套接字socket编程文档.rar_MultiGet-1.1.4_linux_linux socket_linux 编程_soc

    在IT行业中,套接字(Socket)编程是网络通信的核心技术之一,特别是在Unix/Linux系统中。本文档将深入探讨Linux下的Socket编程,包括基础概念、API接口、多线程及多进程的并发处理,以及MultiGet-1.1.4项目在Linux...

    TCP_socket.zip_c linux socket_client.c_linux tcp client_socket_s

    总之,"TCP_socket.zip_c linux socket_client.c_linux tcp client_socket_s"这个压缩包中的代码和头文件展示了如何在Linux环境下使用C语言编写TCP客户端和服务端程序。通过理解这些基本概念和技术,开发者可以构建...

    tcp+udp.rar_TCP/IP_linux udp socket_linux 网络编程_socket linux udp

    创建TCP套接字时,通常会使用`socket()`函数,指定协议族(如AF_INET)和套接字类型(如SOCK_STREAM)。然后,通过`bind()`将套接字绑定到特定的IP地址和端口,`listen()`用于监听连接请求,`accept()`接收连接,...

Global site tag (gtag.js) - Google Analytics