UNIX域协议(命名套接字)
这里主要介绍命名UNIX域套接字
1.什么是UNIX域套接字
Unix域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务通信的一种方式。是进程间通信(IPC)的一种方式。
它提供了两类套接字:字节流套接字(有点像TCP)和数据报套接字(有点像UDP)
UNIX域数据报服务是可靠的,不会丢失消息,也不会传递出错。
IP协议标识客户服务器是通过IP地址和端口号实现的,UNIX域协议中用于标识客户机和服务器的协议地址的是普通文件系统中的路径名。
2.UNIX域协议特点
1)UNIX域套接字域TCP套接字相比,在同一台主机的传输速度前者是后者的两倍。UNIX域套接字仅仅复制数据,并不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不产生顺序号,也不需要发送确认报文
2)UNIX域套接字可以在同一台主机上各进程之间传递文件描述符
3)UNIX域套接字域传统套接字的区别是用路径名表示协议族的描述
3.UNIX域地址结构
#define UNIX_PATH_MAX 128
struct sockaddr_un{
sa_family_t sun_family; /* AF_UNIX 或者 AF_LOCAL */
char sun_path[UNIX_PATH_MAX]; /* path name */
};
4.使用实例,编程套路跟TCP很像。
Server:先创建套接字 -> 绑定地址 -> 监听 -> accept 客户端连接 -> 连接成功开始通信 -> 关闭套接字
Client:先创建套接字 -> 连接server -> 开始通信 -> 关闭套接字。
这里实现一个简单的回射服务器。
启动服务器,等待客户端连接,连接上之后,客户端通过标准输入接收数据发送给服务器。服务器接收数据以后,再把数据发送回客户端。
下面上代码:
server:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <sys/un.h>
//#include<netinet/in.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while()
#define UNIXSOCKETNAME "test_socket"
void echo_cli(int sock)
{
char buf[] = {};
int ret = ;
while()
{
ret = read(sock, buf, sizeof(buf));
if(ret == )
{
printf("client %d close\n", sock);
break;
} write(sock, buf, strlen(buf));
}
close(sock);
}
int main()
{
int listenfd = socket(PF_UNIX, SOCK_STREAM, );
if(listenfd < )
ERR_EXIT("socket");
unlink(UNIXSOCKETNAME);
struct sockaddr_un servaddr; // 头文件是这个 #include <sys/un.h>
memset(&servaddr, , sizeof(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path, UNIXSOCKETNAME);
if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
ERR_EXIT("bind");
if(listen(listenfd, SOMAXCONN) < )
ERR_EXIT("listen");
int conn = ;
pid_t pid;
while()
{
conn = accept(listenfd, NULL, NULL);
if(conn == -)
{
if(errno == EINTR)
continue;
ERR_EXIT("accept");
}
printf("Has new client connected, conn = %d\n", conn);
pid = fork();
if(pid < )
ERR_EXIT("fork");
else if(pid == )
{
echo_cli(conn);
exit();
}
else
close(conn);
}
return ;
}
client:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <sys/un.h>
//#include<netinet/in.h>
#define UNIXSOCKETNAME "test_socket"
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while()
void echo_cli(int sock)
{
char buf1[] = {};
char buf2[] = {};
int ret = ;
while(fgets(buf1, sizeof(buf1), stdin) != NULL)
{
write(sock, buf1, strlen(buf1));
ret = read(sock, buf2, sizeof(buf2));
if(ret == )
{
printf("server %d close\n", sock);
break;
}
printf("%s", buf2);
memset(buf1, , sizeof(buf1));
memset(buf2, , sizeof(buf2));
}
close(sock);
}
int main()
{
int sock = socket(PF_UNIX, SOCK_STREAM, );
if(sock < )
ERR_EXIT("socket");
struct sockaddr_un servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path, UNIXSOCKETNAME);
if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
ERR_EXIT("connect");
echo_cli(sock);
return ;
}
运行:
直接gcc编译,就可以运行了。先启动server,再启动client。
注意:
1)启动server后,bind后会在对应目录创建一个文件(权限是0777&~umask)。这文件的类型是s。表示是套接口文件。可以通过ls -al查看。
srwxrwxr-x 1 xcy xcy 0 1月 3 10:29 test_socket
2)若套接口文件存在,则bind会出错。为此可以先把该文件删掉。(server中的unlink就干这个的)
3)创建的套接口文件最好为绝对路径。建议指定在/tmp目录下。比如把上面的目录改成/tmp/test_socket
3)UNIX域流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED,这和TCP不同,如果监听队列满了,会忽略到来的SYN,这会导致对方重传SYN。
UNIX域协议(命名套接字)的更多相关文章
- Socket编程实践(13) --UNIX域协议
UNIX域协议 UNIX域套接字与TCP相比, 在同一台主机上, UNIX域套接字更有效率, 几乎是TCP的两倍(由于UNIX域套接字不需要经过网络协议栈,不需要打包/拆包,计算校验和,维护序号和应答 ...
- UNIX网络编程读书笔记:UNIX域协议
概述 UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同.UNIX域协议可视为进程间通信 ...
- 《Unix 网络编程》15:Unix 域协议
Unix 域协议 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ 本 ...
- unix网络编程——TCP套接字编程
TCP客户端和服务端所需的基本套接字.服务器先启动,之后的某个时刻客户端启动并试图连接到服务器.之后客户端向服务器发送请求,服务器处理请求,并给客户端一个响应.该过程一直持续下去,直到客户端关闭,给服 ...
- UNP学习笔记(第十五章 UNIX域协议)
UNIX域协议是在单个主机上执行客户/服务器通信的一种方法 使用UNIX域套接字有以下3个理由: 1.UNIX域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍 2.UNIX域套接字可用于在同 ...
- UNP学习 Unix域协议
Unix域协议并不是一个实际的协议族,它只是在同一台主机上进行客户-服务器通信时,使用与在不同主机上的客户和服务器间通信时相同的API的一种方法. 当客户和服务器在同一台主机上时,Unix域协议是这套 ...
- UNIX网络编程——原始套接字的魔力【续】
如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...
- 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现
一.客户端/服务器架构(C/S架构) 即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...
- 基于udp协议的套接字及udp协议粘包问题
udp协议的套接字 udp协议传输 服务端和客户端没有建立连接一说. import socket # 总结一下基础工作流程:服务端生成套接字并绑定ip_port,进入数据传输循环,服务端接受客户端发 ...
随机推荐
- parquet列式文件实战
前言 列式文件,顾名思义就是按列存储到文件,和行式存储文件对应.保证了一列在一个文件中是连续的.下面从parquet常见术语,核心schema和文件结构来深入理解.最后通过java api完成writ ...
- java二进制相关基础
转载请注明原创出处,谢谢! 说在前面 之前在JVM菜鸟进阶高手之路十(基础知识开场白)的时候简单提到了二进制相关问题,最近在看RocketMQ的源码的时候,发现涉及二进制的内容蛮多,jdk源码里面也是 ...
- Java面试常见算法题
1.实现字符串反转 提供七种方案实现字符串反转 import java.util.Stack; public class StringReverse { public static String re ...
- tensorflow入门教程
人工智能感觉很神秘,作为google公司力推的人工智能框架tensorflow也受到很多人的关注.本文用一个最简单的例子,带领大家看看tensorflow是如何工作的.如果你对人工智能的原理不了解可以 ...
- underscore源码解析(一)
留存root // Establish the root object, `window` (`self`) in the browser, `global` // on the server, or ...
- 二叉树的递归遍历 Tree UVa548
题意:给一棵点带权的二叉树的中序和后序遍历,找一个叶子使得他到根的路径上的权值的和最小,如果多解,那该叶子本身的权值应该最小 解题思路:1.用getline()输入整行字符,然后用stringstre ...
- ettercap的中间人欺骗
环境准备:kali系统 因为kali系统自带ettercap,比较方便, 不需要安装 ifcofing命令查看当前网关 ,当前的IP是: 172.16.42.1 查找局域网所有主机 通过netdisc ...
- 【特征匹配】BRISK原文翻译
原文:Stefan Leutenegger, Margarita Chli et al.<BRISK: Binary Robust Invariant Scalable Keypoints> ...
- 【日常学习】【线性DP】codevs1044 拦截导弹题解
题目描写叙述 Description 某国为了防御敌国的导弹突击,发展出一种导弹拦截系统.可是这样的导弹拦截系统有一个缺陷:尽管它的第一发炮弹可以到达随意的高度,可是以后每一发炮弹都不能高于前一发的高 ...
- AVL树 & 重平衡概念
AVL树是有平衡条件的二叉搜索树.这个平衡条件必须容易保持,而且需要保证树的深度是O(logN). AVL=BBST 作为二叉搜索树的最后一部分,我们来介绍最为经典的一种平衡二叉搜索树:AVL树.回顾 ...