一、UNIX Domain Socket
概念:
UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC)
特点:
1. 它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等
2. 只是将应用层数据从一个进程拷贝到另一个进程。
工作模式:
SOCK_DGRAM 类似于UDP
SOCK_STREAM 类似于TCP
用途:
UNIX Domain Socket可用于两个没有亲缘关系的进程,是全双工的,是目前使用最广泛的IPC机制
比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的
二、工作流程
与网络socket的不同点:
1. address family为AF_UNIX
2. unix domain socket不需要IP和端口,取而代之的是文件路径来表示“网络地址”
原理:
UNIXDomain socket用结构体sockaddr_un表示,是一个socket类型的文件在文件系统中的路径
这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回
UNIX Domain Socket客户端一般要显式调用bind函数,而不象网络socket一样依赖系统自动分配的地址。
客户端bind的socket文件名可以包含客户端的pid,这样服务器就可以区分不同的客户端
工作流程:
服务器端:创建socket—绑定文件(端口)—监听—接受客户端连接—接收/发送数据—…—关闭
客户端: 创建socket—绑定文件(端口)—连接—发送/接收数据—…—关闭
三、阻塞和非阻塞(SOCK_STREAM方式)
读写操作有两种操作方式:阻塞和非阻塞
1.阻塞模式下
阻塞模式下,发送数据方和接收数据方的表现情况如同命名管道
2.非阻塞模式
在send或recv函数的标志参数中设置MSG_DONTWAIT,则发送和接收都会返回。如果没有成功,则返回值为-1,errno为EAGAIN 或 EWOULDBLOCK
四.实例
服务端代码:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#define UNIX_DOMAIN "/data/local/tmp/ndk_cmd"
int main(void) {
int listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("cannot create communication socket\n");
return 1;
}
//set server addr_param
struct sockaddr_un srv_addr;
srv_addr.sun_family = AF_UNIX;
strncpy(srv_addr.sun_path, UNIX_DOMAIN, sizeof(srv_addr.sun_path) - 1);
unlink (UNIX_DOMAIN);
//bind sockfd & addr
int ret = bind(listen_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
if (ret == -1) {
perror("cannot bind server socket");
close(listen_fd);
unlink(UNIX_DOMAIN);
return 1;
}
//listen sockfd
ret = listen(listen_fd, 1);
if (ret == -1) {
perror("cannot listen the client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return 1;
}
//have connect request use accept
struct sockaddr_un clt_addr;
int len = sizeof(clt_addr);
int com_fd = accept(listen_fd, (struct sockaddr*) &clt_addr, &len);
if (com_fd < 0) {
perror("cannot accept client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return 1;
}
//read and printf sent client info
printf("/n=====info=====/n");
static char recv_buf[1024];
for (int i = 0; i < 4; i++) {
memset(recv_buf, 0, 1024);
int num = read(com_fd, recv_buf, sizeof(recv_buf));
printf("Message from client (%d)) :%s\n", num, recv_buf);
}
close(com_fd);
close(listen_fd);
unlink(UNIX_DOMAIN);
return 0;
}
客户端代码:
#include <stdio.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
int main(void) {
//creat unix socket
int connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (connect_fd < 0) {
perror("cannot create communication socket");
return 1;
}
static struct sockaddr_un srv_addr;
srv_addr.sun_family = AF_UNIX;
strcpy(srv_addr.sun_path, "/data/local/tmp/ndk_cmd");
//connect server
int ret = connect(connect_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
if (ret == -1) {
perror("cannot connect to the server");
close(connect_fd);
return 1;
}
char snd_buf[1024];
memset(snd_buf, 0, 1024);
strcpy(snd_buf, "message from client");
//send info server
for (int i = 0; i < 4; i++)
write(connect_fd, snd_buf, sizeof(snd_buf));
close(connect_fd);
return 0;
}
运行结果:

- monitor a local unix domain socket like tcpdump
Can I monitor a local unix domain socket like tcpdump? - Super User https://superuser.com/questions/ ...
- 由一个简单需求到Linux环境下的syslog、unix domain socket
本文记录了因为一个简单的日志需求,继而对linux环境下syslog.rsyslog.unix domain socket的学习.本文关注使用层面,并不涉及rsyslog的实现原理,感兴趣的读者可以参 ...
- UNIX DOMAIN SOCKET效率
关于UNIX DOMAIN SOCKET和普通udp socket的对比 在TX1(4核A57 1.7GHz)的板卡上进行测试,每个包大小设置为1024,全速收发,UDS的速度在90Mbps左右,UD ...
- nginx、php-fpm默认配置与性能–TCP socket还是unix domain socket【转】
原文地址:https://www.cnxct.com/default-configuration-and-performance-of-nginx-phpfpm-and-tcp-socket-or-u ...
- (unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误
一个困扰我两天的问题, Google和Baidu没有找到解决方法! 此文为记录这个问题,并给出原因和解决方法. 1.Unix domain socket简介 unix域协议并不是一个实际的协议族,而是 ...
- 问题解决:psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
错误提示: psql: could not connect to server: No such file or directory Is the server running locally and ...
- Unix Domain Socket 域套接字实现
主要注意流程: STREAM SOCKET: Server : socket() ---> bind() ---> listen() ---> accept() Client: ...
- libpqxx接口的在linux下的使用,解决psql:connections on Unix domain socket "/tmp/.s.PGSQL.5432"错误
在项目中使用postgresql数据库时要求在windows和linux双平台兼容.于是在windows下使用的接口在linux下爆出异常: psql:connections on Unix doma ...
- [dev][socket] unix domain socket删除socket文件
问题 在使用unix domain socket的时候,bind之后,会在本地路径里 产生一个与path对应的socket文件. 如何正确的在用完socket之后,对其销毁呢? 方案 使用 unlin ...
随机推荐
- Kafka——分布式消息系统
Kafka——分布式消息系统 架构 Apache Kafka是2010年12月份开源的项目,采用scala语言编写,使用了多种效率优化机制,整体架构比较新颖(push/pull),更适合异构集群. 设 ...
- LevelDB库简介
LevelDB库简介 一.LevelDB入门 LevelDB是Google开源的持久化KV单机数据库,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询 ...
- SSL、OPENSSL、SSH、OPENSSH
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议.TLS与 ...
- HDInsight 路径问题
HDInsight中..上传文件的路径是要区分大小写的.. 很变态吧.. 所以项目中要求全部路径使用小写..
- mysql配置mysql-proxy读写分离
MySQL配置读写分离 192.168.23.131与192.168.23.132两台服务器,131是主,132是从,131是读写,132是只读.myql-proxy的IP是192.168.23.13 ...
- DNX 版本升级命令
一.稳定版本 dnvm install latest -a x86 -r clrdnvm install latest -a x86 -r coreclrdnvm install latest -a ...
- 用apache-cxf生成webservice客户端的时候报错Parameter: shead already exists for method
版本apache-cxf-3.1.0 命令如下:wsdl2java -p com.wz.interfaces -d ./src -client ./ws/xxx.wsdl 报错如下: WSDLToJa ...
- [asp.net core]project.json(1)
摘要 前面介绍了使用vs2015新建asp.net core web的内容,这篇文章学习下project.json文件的内容. project.json 原文:https://docs.microso ...
- 关于 jquery 选择器的 深入理解 -1
多级选择器: 前面一个selector1, 后面通过 //空格, >, + ~, 各种筛选 选择器 + selector2 // 再次进行选择的,就叫做多级选择器 jquery的一个基本常识: ...
- linux shell 报错 Syntax error: Bad for loop variable
在linux下写了一个简单的shell,循环10次. test.sh #!/bin/bash ## ##循环10次 ## ; i<; i++)); do echo Good Morning ,t ...