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,进入数据传输循环,服务端接受客户端发 ...
随机推荐
- redis—操作基础
内存数据库: 1.双击redis-server.exe =>启动2.双击redis-cli.exe =>打开管理控制台3.查看所有key keys *4.查看key类型 type myKe ...
- 虚拟机创建流程中neutron代码分析(二)
前言: 当nova服务发送了创建port的restful调用信息之后,在neutron服务中有相应的处理函数来处理调用.根据restful的工作原理,是按照 paste.ini文件中配置好的流程去处理 ...
- web管理kvm ,安装webvirtmgr
原创博文安装配置KVM http://www.cnblogs.com/elvi/p/7718574.htmlweb管理kvm http://www.cnblogs.com/elvi/p/7718582 ...
- POJ2251-Dungeon Master
题意:给出一三维空间的地牢,要求求出由字符'S'到字符'E'的最短路径移动方向可以是上,下,左,右,前,后,六个方向,每移动一次就耗费一分钟,要求输出最快的走出时间.不同L层的地图,相同RC坐标处是连 ...
- 创建一个servlet
servlet: 它是web应用程序的核心类,可以直接处理和相应用户请求,又或者将处理工作委托给应用中的其他部分的类. 让servlet继承HttpServlet的原因是: 1.HttpServlet ...
- 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖
前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...
- “IAsyncOperation<StorageFile>”不包含“GetAwaiter”的定义
错误 CS4036 "IAsyncOperation<StorageFile>"不包含"GetAwaiter"的定义,并且找不到可接受类型为&quo ...
- 谷哥的小弟学前端(11)——JavaScript基础知识(2)
探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 具体解释Android主流框架不可或缺的基石 站在源代码的肩膀上全解Scroller工作机制 Android多分辨率适 ...
- 用KMP算法实现strStr()
strStr()函数的用途是在一个字符串S中寻找某个字串P第一次出现的位置.并返回其下标,找不到时返回-1.最简单的办法就是找出S全部的子串和P进行比較,然而这种方法比較低效.假设我们从S的下标0和P ...
- SpringMVC+Mybatis架构中的问题记录
2014/08/16 记录 今天遇到个问题.折腾了我大约4个小时,好坑啊由于之前没遇到过 我的包是这么分的:com.project名.模块名.service.impl 在spring 配置这个 ...