l8-d13 UNIX域套接字

一、UNIX 域流式套接字

本地地址

struct sockaddr_un {

unsigned short sun_family; /* 协议类型 */

char sun_path[108]; /* 套接字文件路径 */

};

UNIX 域流式套接字的用法和 TCP 套接字基本一致,区别在于使用的协议和地址不同

UNIX 域流式套接字服务器端流程如下:

(1)创建 UNIX 域流式套接字。

(2)绑定本地地址(套接字文件)。

(3)设置监听模式。

(4)接收客户端的连接请求。

(5)发送/接收数据。

UNIX 域流式套接字客户端流程如下。

(1)创建 UNIX 域流式套接字。

(2)指定服务器端地址(套接字文件)。

(3)建立连接。

(4)发送/接收数据。

UNIX 域用户数据报套接字的流程可参考 UDP 套接字

UNIX 域流式套接字服务器端流程如下:

(1)创建 UNIX 域流式套接字。

(2)绑定本地地址(套接字文件)。

(3)发送/接收数据。

二、UNIX域流式套接字实现

服务端

cpp 复制代码
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define MY_SOCK_PATH "/tmp/my_sock_file"
#define LISTEN_BACKLOG 50

#define handle_error(msg) \
	do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
	int sfd, cfd;
	struct sockaddr_un my_addr, peer_addr;
	socklen_t peer_addr_size;
	char buf[BUFSIZ] = {};

	sfd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sfd == -1)
		handle_error("socket");

	memset(&my_addr, 0, sizeof(struct sockaddr_un));
	my_addr.sun_family = AF_UNIX;
	strncpy(my_addr.sun_path, MY_SOCK_PATH,
			sizeof(my_addr.sun_path) - 1);

	if (bind(sfd, (struct sockaddr *) &my_addr,
				sizeof(struct sockaddr_un)) == -1)
		handle_error("bind");
	if (listen(sfd, LISTEN_BACKLOG) == -1)
		handle_error("listen");

	peer_addr_size = sizeof(struct sockaddr_un);
	cfd = accept(sfd, (struct sockaddr *) &peer_addr,
			&peer_addr_size);
	if (cfd == -1)
		handle_error("accept");
	
	recv(cfd, buf, BUFSIZ, 0);
	printf("%s\n", buf);

	close(cfd);
	close(sfd);
	remove(MY_SOCK_PATH);
	return 0;
}

客户端

cpp 复制代码
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define MY_SOCK_PATH "/tmp/my_sock_file"

#define handle_error(msg) \
	do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
	int fd;
	struct sockaddr_un peer_addr;
	char buf[BUFSIZ] = {"Hello World!"};

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd == -1)
		handle_error("socket");

	memset(&peer_addr, 0, sizeof(struct sockaddr_un));
	peer_addr.sun_family = AF_UNIX;
	strncpy(peer_addr.sun_path, MY_SOCK_PATH,
			sizeof(peer_addr.sun_path) - 1);

	if (connect(fd, (struct sockaddr *) &peer_addr,
				sizeof(struct sockaddr_un)) == -1)
		handle_error("connect");

	printf("%s\n",buf);
	send(fd, buf, strlen(buf), 0);

	close(fd);
	return 0;
}

三、UNIX域数据报套接字实现

服务端

cpp 复制代码
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define MY_SOCK_PATH "/tmp/my_sock_file"
#define handle_error(msg) \
	do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
	int fd;
	struct sockaddr_un my_addr, peer_addr;
	socklen_t peer_addr_size;
	char buf[BUFSIZ] = {};

	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
	if (fd == -1)
		handle_error("socket");

	memset(&my_addr, 0, sizeof(struct sockaddr_un));
	my_addr.sun_family = AF_UNIX;
	strncpy(my_addr.sun_path, MY_SOCK_PATH,
			sizeof(my_addr.sun_path) - 1);

	if (bind(fd, (struct sockaddr *) &my_addr,
				sizeof(struct sockaddr_un)) == -1)
		handle_error("bind");

	peer_addr_size = sizeof(struct sockaddr_un);
	recvfrom(fd, buf, BUFSIZ, 0, (struct sockaddr *) &peer_addr,
			&peer_addr_size);
	printf("%s\n",buf);
	close(fd);
	remove(MY_SOCK_PATH);
	return 0;
}

客户端

cpp 复制代码
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define MY_SOCK_PATH "/tmp/my_sock_file"
#define handle_error(msg) \
	do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
	int fd;
	struct sockaddr_un peer_addr;
	socklen_t peer_addr_size;
	char buf[BUFSIZ] = {"Hello World!"};

	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
	if (fd == -1)
		handle_error("socket");

	memset(&peer_addr, 0, sizeof(struct sockaddr_un));
	peer_addr.sun_family = AF_UNIX;
	strncpy(peer_addr.sun_path, MY_SOCK_PATH,
			sizeof(peer_addr.sun_path) - 1);

	peer_addr_size = sizeof(struct sockaddr_un);
	printf("%s\n", buf);
	sendto(fd, buf, strlen(buf), 0, (struct sockaddr *) &peer_addr,
			peer_addr_size);
	close(fd);
	remove(MY_SOCK_PATH);
	return 0;
}
相关推荐
EricWang135818 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
算法与编程之美1 小时前
文件的写入与读取
linux·运维·服务器
JaneJiazhao2 小时前
HTTPSOK:SSL/TLS证书自动续期工具
服务器·网络协议·ssl
萨格拉斯救世主3 小时前
戴尔R930服务器增加 Intel X710-DA2双万兆光口含模块
运维·服务器
无所谓จุ๊บ3 小时前
树莓派开发相关知识十 -小试服务器
服务器·网络·树莓派
Jtti3 小时前
Windows系统服务器怎么设置远程连接?详细步骤
运维·服务器·windows
yeyuningzi3 小时前
Debian 12环境里部署nginx步骤记录
linux·运维·服务器
EasyCVR4 小时前
萤石设备视频接入平台EasyCVR多品牌摄像机视频平台海康ehome平台(ISUP)接入EasyCVR不在线如何排查?
运维·服务器·网络·人工智能·ffmpeg·音视频
龙哥说跨境5 小时前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
pk_xz1234567 小时前
Shell 脚本中变量和字符串的入门介绍
linux·运维·服务器