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域的本地进程通信客户端服务端通信源码”指的是在Unix/Linux系统中使用AF_UNIX(也称为AF_LOCAL)套接字协议族进行进程间通信(IPC)的代码实现。这种通信方式适用于同一台机器上的不同进程之间...
AF_UNIX套接字主要在本地系统中使用,它们不需要网络支持,因此通信速度更快,且不受网络协议的限制。通信双方通过文件描述符(file descriptor)来识别对方,通常是一个隐藏的文件路径。这种方式适用于需要高性能、...
首先,`socket`是Unix和类Unix系统(包括Linux)中的一个API接口,它允许程序员创建网络连接并进行数据传输。在Linux下,Socket通信通常涉及以下步骤: 1. **创建Socket**:使用`socket()`函数创建一个Socket描述符...
af_unixaf_unixaf_unixaf_unix 使用
以上示例展示了如何使用QT的`QTcpSocket`类和Linux Socket API来实现客户端与服务器之间的通信。通过这种方式,开发人员可以在QT应用程序中充分利用Linux的底层网络功能,从而实现更复杂的应用场景。
该函数需要指定套接字类型和协议族,如AF_UNIX(用于本地通信)或AF_INET(用于网络通信)。 2. **绑定**:使用`bind()`函数将套接字与特定的地址(通常是文件路径或IP地址和端口号)关联起来,这样其他进程就可以...
使用`socket()`函数创建一个socket,需要指定协议族(如AF_INET代表IPv4)、套接字类型(如SOCK_STREAM代表TCP)和协议(通常是0,系统会自动选择默认的TCP或UDP协议)。 3. **bind函数绑定**: `bind()`函数用于...
junixsocket junixsocket是一个Java / JNI库,允许使用Java的(AF_UNIX套接字)。为什么很酷junixsocket是一个小型的模块化库。 仅安装您需要的内容。 与其他实现相反, junixsocket扩展了Java Sockets API( java...
- 使用`socket()`函数创建一个Socket,需要指定协议族(如AF_INET用于IPv4,AF_INET6用于IPv6),套接字类型(如SOCK_STREAM为TCP,SOCK_DGRAM为UDP)以及协议(通常为0,由系统自动选择)。 3. **绑定Socket**: ...
在本地环境中,Socket通讯主要使用AF_UNIX或者PF_UNIX域,也被称为Unix域Socket。这种类型的Socket允许同一主机上的不同进程共享数据,其效率通常比其他IPC机制(如管道、消息队列、共享内存等)更高,因为它们不...
在Linux系统中,TCP(Transmission Control Protocol)套接字是实现客户端与服务器间可靠通信的基础。本教程将探讨如何在Linux环境下使用C语言编写TCP socket的客户端和服务器程序。TCP是一种面向连接的、可靠的传输...
1. 创建套接字:使用`socket()`函数创建一个新的套接字,指定协议类型(如TCP)和地址族(如AF_INET)。 2. 绑定地址:使用`bind()`函数将套接字与特定的IP地址和端口号绑定,以便客户端可以找到服务器。 3. 监听...
创建一个socket,通常需要调用`socket()`函数,指定协议族(如AF_INET代表IPv4)、套接字类型(SOCK_DGRAM对应UDP)以及协议(通常是0,系统会自动选择UDP)。 接下来,我们关注UDP套接字的使用。与TCP套接字不同,...
在Linux系统中,网络通信是通过套接字(Socket)接口来实现的,这是一种标准的进程间通信(IPC)机制,常用于实现客户端与服务器之间的数据交换。在本压缩包"linux_socket_thread.zip"中,包含的是一个使用C语言编写...
1. 创建套接字:使用`socket()`函数创建一个CAN套接字,指定地址族为AF_CAN。 2. 绑定套接字:使用`bind()`函数将套接字与CAN接口关联,如`"can0"`。 3. 设置过滤器:使用`setsockopt()`函数设置CAN过滤器,筛选接收...
在IT行业中,网络通信是计算机科学的一个重要领域,而Socket编程是实现网络通信的基础。本教程将通过一个简单的C语言实现的Socket通信实例,讲解如何在VC++6.0环境下进行Socket编程。这个实例包括了服务端和服务端两...
2. **创建Socket**:调用`socket()`函数创建一个socket描述符,指定协议类型(如TCP或UDP)和地址族(通常为AF_INET,表示IPv4)。 3. **配置Socket**:对于服务器端,需要调用`bind()`函数将socket绑定到特定的IP...
在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"这个压缩包中的代码和头文件展示了如何在Linux环境下使用C语言编写TCP客户端和服务端程序。通过理解这些基本概念和技术,开发者可以构建...
创建TCP套接字时,通常会使用`socket()`函数,指定协议族(如AF_INET)和套接字类型(如SOCK_STREAM)。然后,通过`bind()`将套接字绑定到特定的IP地址和端口,`listen()`用于监听连接请求,`accept()`接收连接,...