Linux本地套接字(Unix域套接字)----SOCK_DGRAM方式

目录

 

简述

创建服务端代码:

创建客户端代码

接收函数封装

发送封装

服务端测试main函数

客户端测试main函数

编译运行结果


简述

这里介绍一下Linux进程间通信的socket方式---Local socket。这篇主要是介绍下SOCK_DGRAM方式的通信,即数据包的方式(与UDP类似),面向无连接。

这个代码是我刚开始学的时候写的,代码比较简单,适合初学,学习最快的方式就是直接拿源码修改、编译运行、调试。

完整源代码:https://gitee.com/fensnote/demo_code/tree/master/Linux/unix_socket

 

创建服务端代码:

int startServer()
{
    int iRet;

	TSockAddrUn serv_unadr;
	TSockAddrIn serv_inadr;
	TSockAddr   *pSockAddr = NULL;

	bzero(&serv_unadr,sizeof(serv_unadr));
	bzero(&serv_inadr,sizeof(serv_inadr));

	serv_unadr.sun_family = AF_UNIX;
	strcpy(serv_unadr.sun_path,UNIX_SOCKET_PATH);

	pSockAddr = (TSockAddr *)&serv_unadr;
	
	signal(SIGPIPE, SIG_IGN);


	/* 创建本地socket */
	sockFd = socket(AF_UNIX, SOCK_DGRAM, 0);//数据包方式
	if ( sockFd <= 0)
	{
	    perror("socket error");
	    return sockFd;
	}

	/* 绑定监听口 */
    int flag = 1;
    iRet = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

    setSocketAttr(sockFd);

    unlink(UNIX_SOCKET_PATH);
	iRet = bind(sockFd, pSockAddr, sizeof(TSockAddr));
	if (iRet != 0)
	{
	    perror("bind error");
		close(sockFd);
		return -1;
	}


    return sockFd;
}

创建客户端代码

面向无连接的方式,和服务端的代码差别不大:

int InitUdpClient()
{

	TSockAddrUn unadr;
	TSockAddr   *pSockAddr = NULL;

	bzero(&unadr,sizeof(unadr));

	char tmpPath[] = "/tmp/unix_XXXX";
	char *tmpName = mktemp(tmpPath);

	unadr.sun_family = AF_LOCAL;
	strcpy(unadr.sun_path, tmpName);

	pSockAddr = (TSockAddr *)&unadr;


	/* 创建本地socket */
	sockFd = socket(AF_LOCAL, SOCK_DGRAM, 0);//数据包方式
	if ( sockFd <= 0)
	{
	    perror("CUdpClient:: socket error");
	    return sockFd;
	}
	
	unlink(tmpPath);

	/* 绑定监听口 */
    //setSocketAttr(sockFd);
	int iRet = bind(sockFd,pSockAddr, sizeof(TSockAddr));
	if (iRet != 0)
	{
	    perror("bind error");
		close(sockFd);
		return -1;
	}

    return sockFd;
}

接收函数封装

//返回0 超时  timeOut-超时时间
int UnixRead(char *recvBuf, int len, int timeOut)
{
	int nRead = readable_timeo(sockFd, timeOut);
	if ( nRead <= 0 )
	{
		printf("UnixRead, read time out!\n");
		return 0;
	}

	pSockAddr = (TSockAddr *)&unClientaddr;
	socklen  = sizeof(TSockAddrUn);

	bzero(recvBuf, len);
	
	nRead = recvfrom(sockFd, recvBuf, len, 0, pSockAddr, &socklen);
	if ( nRead <= 0 )
	{
		if ( (EAGAIN == errno) || (EINTR == errno))
		{
			return 0;   //接收连接超时
		}

		perror("UnixRead read error:");
	}
	
	return nRead;
}

发送封装

int UnixSend(const void *data, int len)
{
	TSockAddrUn unadr;
	TSockAddr   *pSockAddr = NULL;

	bzero(&unadr,sizeof(unadr));
	
	unadr.sun_family = AF_LOCAL;
	strcpy(unadr.sun_path, UNIX_SOCKET_PATH);

	pSockAddr = (TSockAddr *)&unadr;
	socklen_t socklen  = sizeof(TSockAddrUn);

	return sendto(sockFd, data, len, 0, pSockAddr, socklen);
}

服务端测试main函数

int main()
{
	startServer();
	int nRead = 0;
	
	
	char recvBuf[1024] = {0}; 	
	
	while(1)
	{		
		nRead = UnixRead(recvBuf, 1024, 5);
		if ( nRead <= 0 )
		{
			continue;
		}
		else
		{
			printf("recv %d data: %s\n",nRead, recvBuf);
			const char *sendMsg = "svr ack!";
			UnixSend(sendMsg, strlen(sendMsg));
		}
		
		sleep(1);
	}
	
	
	
	return 0;
}

客户端测试main函数

 int main(  )
 {
	 int sockFd = InitUdpClient();
	 
	 int nRead = 0;

	 const char *sendMsg = "hello";
	 char recvBuf[1024] = {0};
	 while(1)
	 {
			
		nRead = UnixSend(sendMsg, strlen(sendMsg));
		printf("send %d data: %s\n", nRead, sendMsg);
	
		nRead = UnixRead(recvBuf, 1024, 5);
		printf("recv %d data: %s\n", nRead, recvBuf);
		sleep(2);
	 }
	 return 0;
 }

编译运行结果

左边是服务端,右边是客户端。

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fensnote

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值