UNIX域套接字

目录

  • 一、UNIX 域流式套接字
    • UNIX 域流式套接字服务器端流程
    • UNIX 域流式套接字客户端流程
  • 二、UNIX 域数据报套接字
    • UNIX 域数据报套接字服务器端流程
    • UNIX 域数据报套接字客户端流程

一、UNIX 域流式套接字

struct sockaddr_un {
  unsigned short sun_family;    /* 协议类型 */
  char sun_path[108];        /* 套接字文件路径 */
};

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

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

如下:
(1)创建 UNIX 域流式套接字。
(2)绑定本地地址(套接字文件)。
(3)设置监听模式。
(4)接收客户端的连接请求。
(5)发送/接收数据。

实现代码:
server.c

#include 
#include 
#include 
#include 
#include 
#include 

#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] = {};
/*1 */
	sfd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sfd == -1)
		handle_error("socket");
/*2 */
	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);
/*3 */
	if (bind(sfd, (struct sockaddr *) &my_addr,
				sizeof(struct sockaddr_un)) == -1)
		handle_error("bind");
/*4 */
	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");
/*5 */	
	recv(cfd, buf, BUFSIZ, 0);
	printf("%s\n", buf);

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

UNIX 域流式套接字客户端流程

如下:
(1)创建 UNIX 域流式套接字。
(2)指定服务器端地址(套接字文件)。
(3)建立连接。
(4)发送/接收数据。
实现代码:
client.c

#include 
#include 
#include 
#include 
#include 
#include 

#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!"};
/*1 */
	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd == -1)
		handle_error("socket");
/*2 */
	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);
/*3 */
	if (connect(fd, (struct sockaddr *) &peer_addr,
				sizeof(struct sockaddr_un)) == -1)
		handle_error("connect");
/*4 */
	printf("%s\n",buf);
	send(fd, buf, strlen(buf), 0);

	close(fd);
	return 0;
}

二、UNIX 域数据报套接字

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

UNIX 域数据报套接字服务器端流程

如下:
(1)创建 UNIX 域数据报套接字。
(2)绑定本地地址(套接字文件)。
(3)发送/接收数据。

实现代码:
server.c

#include 
#include 
#include 
#include 
#include 
#include 

#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;
}

UNIX 域数据报套接字客户端流程

如下:
(1)创建 UNIX 域数据报套接字。
(2)信息发送服务器端。

实现代码:
client.c

#include 
#include 
#include 
#include 
#include 
#include 

#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;
}

你可能感兴趣的:(unix,服务器)