linux-UNIX socket

UNIX域套接字

域套接字作为进程间通信的一种手段,值得我们研究一下。


域套接字实现本地进程间通信,同样有服务端和客户端之分。一个进程作为客户端,另一个进程作为服务端。这个和TCP socket类似,但是不一样。域套接字不经过底层网络。数据结构使用的是struct  sockaddr_un。对于这个结构,重点便是填充sun_family和sun_path,sun_path是文件路径。调用的socket接口也是socket、bind、listen、accept、connect、close这些,实际用起来可以看一下细节。

#include <sys/un.h>
struct sockaddr_un {
	sa_family_t sun_family;	/* AF_UNIX */
	char sun_path[UNIX_PATH_MAX];	/* pathname */
};

服务端通信过程

1、socket()建立socket对象,指定协议类型为AF_LOCAL或者AF_UNIX

2、bind()绑定socket对象和socket类型的文件“server socket”

warnning:这里需要关注一下“server socket”这个文件。网络编程中,绑定的是ip和port,但是这里需要绑定的是socket类型的文件,如果在绑定之前,这个文件已经存在,则绑定会失败,因此,需要在bind之前和close之后,删除这个文件。

3、llisten()监听socket对象

4、accept()等待连接

5、read、write读写连接的socket对象,进行数据通信

6、close关闭连接的socket对象


客户端通信过程

1、socket()建立socket对象,指定协议类型为AF_LOCAL或者AF_UNIX

2、connet()连接服务端

3、连接成功开始数据通信

4、通信完成,close关闭socket


服务端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define MAX_SIZE 		1024
#define SOCKET_BACKLOG	1
#define SOCKET_STR 		"server_socket"
#define EXIT_STR		"exit"

/* server */
int main()
{
	int serFd,serConFd;
	int cli_len, nBytes;
	struct sockaddr_un serAddr;
	struct sockaddr_un cliAddr;
	char msg[MAX_SIZE];

	unlink(SOCKET_STR);
	serFd = socket(AF_LOCAL, SOCK_STREAM, 0);
	memset(&serAddr, 0, sizeof(struct sockaddr_un));
	serAddr.sun_family = AF_LOCAL;
	strcpy(serAddr.sun_path, SOCKET_STR);
	bind(serFd, (struct sockaddr*)&serAddr, sizeof(struct sockaddr_un));
	listen(serFd, SOCKET_BACKLOG);
	cli_len = sizeof(struct sockaddr_un);
	printf("server is waiting for connection...\n");
	serConFd = accept(serFd, (struct sockaddr*)&cliAddr, &cli_len);
	printf("server-client connect established...\n");
	while(1){
		memset(msg, 0, MAX_SIZE);
		nBytes = read(serConFd, msg, MAX_SIZE);
		if (nBytes>0){
			printf("server recv:%s\n", msg);
			if (!strcmp(msg, EXIT_STR)) break;
		}
	}
	close(serConFd);
	unlink(SOCKET_STR);
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define MAX_SIZE 		1024
#define SOCKET_BACKLOG	1
#define SOCKET_STR 		"server_socket"
#define EXIT_STR		"exit"

/* client */
int main()
{
	int cliFd, iRet;
	struct sockaddr_un serAddr;
	char msg[MAX_SIZE];

	cliFd = socket(AF_LOCAL, SOCK_STREAM, 0);
	memset(&serAddr, 0, sizeof(struct sockaddr_un));
	serAddr.sun_family = AF_LOCAL;
	strcpy(serAddr.sun_path, SOCKET_STR);
	iRet = connect(cliFd, (struct sockaddr*)&serAddr, sizeof(struct sockaddr_un));
	if (-1 == iRet)
		exit(0);
	printf("server-client connect established...\n");
	while(1){
		memset(msg, 0, MAX_SIZE);
		fgets(msg, MAX_SIZE, stdin);
		if (msg[0] != '\n')
			msg[strlen(msg)-1] = '\0';
		write(cliFd, msg, strlen(msg));
		if (!strcmp(msg, EXIT_STR)) break;
	}
	close(cliFd);
	exit(0);
}

结果截图:


 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值