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

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

 目录

简述

创建服务端代码:

创建客户端代码

接收函数封装

发送封装

服务端测试main函数

客户端测试main函数

编译运行结果


简述

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

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

完整源代码:零散Demo代码: 平时写的一些示例代码基本框架,封装,自定义控件等 - Gitee.com

创建服务端代码:

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

image.gif

创建客户端代码

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

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

image.gif

接收函数封装

//返回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;
}

image.gif

发送封装

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

image.gif

服务端测试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;
}

image.gif

客户端测试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;
 }

image.gif

编译运行结果

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

image.gif编辑


目录
相关文章
|
6月前
|
网络协议 Unix 数据安全/隐私保护
UNIX域套接字接口相似性
UNIX域套接字接口相似性
59 4
|
6月前
|
监控 安全 Unix
UNIX域套接字(Unix Domain Socket)在安全性和隐私性
UNIX域套接字(Unix Domain Socket)在安全性和隐私性
256 2
|
6月前
|
存储 Shell Linux
【Shell 命令集合 网络通讯 】Linux 显示Unix-to-Unix Copy (UUCP) 系统的状态信息 uustat命令 使用指南
【Shell 命令集合 网络通讯 】Linux 显示Unix-to-Unix Copy (UUCP) 系统的状态信息 uustat命令 使用指南
69 0
|
23天前
|
Unix 物联网 大数据
操作系统的演化与比较:从Unix到Linux
本文将探讨操作系统的历史发展,重点关注Unix和Linux两个主要的操作系统分支。通过分析它们的起源、设计哲学、技术特点以及在现代计算中的影响,我们可以更好地理解操作系统在计算机科学中的核心地位及其未来发展趋势。
|
1月前
|
网络协议 Linux
linux学习之套接字通信
Linux中的套接字通信是网络编程的核心,允许多个进程通过网络交换数据。套接字提供跨网络通信能力,涵盖本地进程间通信及远程通信。主要基于TCP和UDP两种模型:TCP面向连接且可靠,适用于文件传输等高可靠性需求;UDP无连接且速度快,适合实时音视频通信等低延迟场景。通过创建、绑定、监听及读写操作,可以在Linux环境下轻松实现这两种通信模型。
31 1
|
3月前
|
Ubuntu 安全 Unix
在Linux中,有哪几种linux/unix发行版本?
在Linux中,有哪几种linux/unix发行版本?
|
3月前
|
Ubuntu Unix Linux
在Linux中,Unix和Linux之间的关系是什么?
在Linux中,Unix和Linux之间的关系是什么?
|
3月前
|
Unix Linux 程序员
Unix:Linux的“逗趣祖师爷”与它的不凡传承
在科技长河中,Unix犹如一颗恒星,既是历史见证者也是未来的启发者。1969年,因程序员肯·汤普森想在他的PDP-7上玩“Space Travel”游戏,意外创造了Unix,以简洁优雅的代码改变了操作系统的世界。进入90年代,林纳斯·托瓦兹受Unix启发,开发了开源免费的Linux,像是Unix调皮的孙子,不仅继承其精髓还增添了开放共享的精神。Unix与Linux之间的传承,就像是智者与追蝶孩童的故事,充满了岁月的智慧与新生的活力,提醒我们科技传奇往往源于不起眼的小事。下次使用Linux时,不妨会心一笑吧!
53 0
|
3月前
|
开发框架 Unix Linux
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
48 0
|
5月前
|
Linux
dbus-cleanup-sockets`:Linux 中的 D-Bus 套接字清理工具
`dbus-cleanup-sockets` 是一个用于清理 Linux 中未正常关闭的 D-Bus 套接字文件的工具,旨在解决资源占用和潜在通信问题。通常在系统启动、关闭或检测到残留套接字时自动运行。用户可手动以 root 权限执行 `/usr/bin/dbus-cleanup-sockets` 进行清理。该工具对于处理系统崩溃或守护进程异常终止导致的残留文件十分有用。