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,进入数据传输循环,服务端接受客户端发 ...
随机推荐
- Foundation框架中日期的操作
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { NSDate *date1=[NSD ...
- 腾讯 AI Lab 计算机视觉中心人脸 & OCR团队近期成果介绍(3)
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:周景超 在上一期中介绍了我们团队部分已公开的国际领先的研究成果,近期我们有些新的成果和大家进一步分享. 1 人脸进展 人脸是最重要的视觉 ...
- Python测试开发之函数
对于初学者而言,感觉函数还是不是很好理解,尤其是当写一个脚本,或者是写一个算法,认为可能for循环就已经可以解决的问题为什么还要用函数来实现呢? 今天就来说一下函数的优点,其实函数的最大优点就是可重用 ...
- Django学习(2)数据宝库
数据库是一所大宝库,藏着各种宝贝.一个没有数据库的网站,功能有限.在Django中,支持的数据库有以下四种: SQLite3 MySQL PostgreSQL Oracle 其中SQLite3为Dja ...
- 51nod 1058 N的阶乘的长度 位数公式
1058 N的阶乘的长度基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3.Input输入N( ...
- C++课程设计报告总结
C++课程设计报告 学院:计算机学院 班级:计科141班 姓名:刘建伟 学号:201400814125 指导老师:王璐 C++课程设计实验报告 学号:2014008 ...
- CDH集群搭建部署
1. 硬件准备 使用了五台机器,其中两台8c16g,三台4c8g.一台4c8g用于搭建cmServer和NFS服务端,另外4台作为cloudera-manager agent部署CDH集群. ...
- day1-Python入门
百度云有关文档资料链接 链接:https://pan.baidu.com/s/1pLighnX 密码:j69s
- JavaScript实现策略模式
在开篇之前先分享今天看到的一句关于设计模式的话:将不变的部分和变化的部分隔开是每个设计模式的主题 请大家自行感受这句话的精髓所在,并且思考学习设计模式究竟能给我们编程带来什么样的东西,欢迎大家在文章下 ...
- 中小企业为什么要上HR系统
人力资源不不过公司资源.也是一种社会资源. 越来越多的企业已将人作为一种重要的资源来看待,资金和技术则是其次.所以企业内部科学的全面的人力资源管理也因此处在了十分重要的位置上. 现在的人力资源是服务于 ...