unix Socket进程间通信

本文展示了如何使用C语言实现UNIX域套接字进行客户端和服务器之间的通信。客户端创建套接字并连接到服务器,而服务器监听连接,接收客户端消息并回应。关键步骤包括socket创建、bind、connect、listen和accept。注意在bind前需要unlink确保路径唯一,accept时传入socklen_t类型长度。

结构体部分介绍

typs.h
# define __STD_TYPE     typedef
#define __U32_TYPE      unsigned int
__STD_TYPE __U32_TYPE __socklen_t;
unistd.h
typedef __socklen_t socklen_t;

linux/un.h
#define UNIX_PATH_MAX   108
struct sockaddr_un {
    sa_family_t    sun_family;    /*AF_UNIX*/
    char           sun_path[108];  /*pathname*/
}

示例:
client 部分的代码

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

int main(int argc, char *argv[])
{
	unsigned char s[1024];
	int clientFd;
	struct sockaddr_un serverAddr;
	
	if((clientFd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
	{
		printf("create socket failed\n");
		return -1;
	}

	memset(&serverAddr, 0x00, sizeof(struct sockaddr_un));
	serverAddr.sun_family = AF_UNIX;
	memcpy(serverAddr.sun_path, argv[1], strlen(argv[1]));
	printf("path: %s\n", argv[1]);
	unlink(argv[1]);

	if (connect(clientFd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr_un)) == -1)
	{
		printf("connect failed %d, %s\n", errno,strerror(errno));
		return -2;
	} 
	while(1){
		scanf("%s\n", s);
		write(clientFd, s, strlen(s));
	}
	
	printf("Exit\n");
	close(clientFd);
	
	return 0;
}

server部分的代码

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

int main(int argc, char *argv[])
{
	int serverFd, clientFd;
	unsigned char buff[1024];
	struct sockaddr_un clientAddr,serverAddr;
	
	if ((serverFd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
	{
		printf("create socket failed\n");
		return -1;
	}
	
	memset(&serverAddr, 0x00, sizeof(struct sockaddr_un));
	serverAddr.sun_family = AF_UNIX;
	memcpy(serverAddr.sun_path, argv[1], strlen(argv[1]));
	unlink(argv[1]);

	if (bind(serverFd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr_un)) == -1)
	{
		printf("bind socket failed\n");
		return -2;
	}
	
	if (listen(serverFd, 1024) == -1)
	{
		printf("listen failed\n");
		return -3;
	}	
	
	printf("Enter Accept\n");
	int len = sizeof(struct sockaddr_un);
	while(1)
	{
		if((clientFd = accept(serverFd, (struct sockaddr *)&clientAddr, (socklen_t *)&len)) == -1) {
			printf("accept failed,%d, %s\n",errno, strerror(errno));
			continue;
		}

		printf("clientFd = %d, sun_path = %s\n", clientFd, clientAddr.sun_path); 
		while(1){
			len = read(clientFd, buff, 1024);
			buff[len] = '\0';
			printf("%s\n", buff);
		}
		sleep(2);
		close(serverFd);
		break;
	}			
	printf("Exit\n");
	return 0;
}

注:
1)服务端accept时的长度要转为socklen_t ,
否则在会出现accept failed,14, Bad address
2)在bind之前要确定文件不存在,即要执行unlink操作
3)执行命令 :./a.out ./hello.txt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值