前言:

127.0.0.1它是一个私有IP,代表的就是你的本机环回地址,其实本质上是绑定在虚拟网卡loopback上的IP。

在实际应用中,有遇到在使用本地回环做进程间通讯的时候程序阻塞的情况。比如下面代码

(一)本地回环:

客户端数据收发程序:

static int send_recv(char *cmd, int *ret, char* strResult, int nSize)
{
struct sockaddr_in sin;
struct sockaddr_in cin;
int port = PORT_FOR_SYSTEM;
socklen_t addr_len;
int s_fd;
int n;
ST_CMD_RESULT stCmdResult = {0};
fd_set rfds;
ST_CMD stCmd = {0}; if (0 >= nSize || NULL == strResult)
stCmd.bNeedResult = 0;
else
stCmd.bNeedResult = 1;
strncpy(stCmd.strCmd, cmd, MAX_CMD_LEN); bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
sin.sin_port = htons(port); s_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(s_fd == -1)
{
printf("create socket failed!\n");
return -1;
} n = sendto(s_fd, &stCmd, sizeof(stCmd.bNeedResult) + strlen(stCmd.strCmd) + 1, 0, (struct sockaddr *) &sin, sizeof(sin));
if(n == -1)
{
printf("send failed!\n");
close(s_fd);
return -1;
} FD_ZERO(&rfds);
FD_SET(s_fd, &rfds); if(stCmd.bNeedResult)
{
struct timeval tv_out;
tv_out.tv_sec = 5;
tv_out.tv_usec = 0;
n = select(s_fd+1, &rfds, NULL, NULL, &tv_out);
}
else
{
n = select(s_fd+1, &rfds, NULL, NULL, NULL);
} if (n == -1)
{
printf("select error!\n");
close(s_fd);
return -1;
}
else if(n == 0)
{
printf("recvfrom timeout!\n");
close(s_fd);
return -1;
} addr_len = sizeof(cin);
n = recvfrom(s_fd, &stCmdResult, sizeof(stCmdResult), 0, (struct sockaddr *) &cin, &addr_len);
*ret = stCmdResult.ret;
strncpy(strResult, stCmdResult.strResult, nSize);
if(n == -1)
{
printf("recvfrom failed!\n");
close(s_fd);
return -1;
} close(s_fd); return 0;
}

上面接口主要实现下面几个功能:

  1. 以本地环形地址为目标IP建立一个UDP链接
  2. 往链接中写入数据
  3. 根据是否需要应答设置不同的超时模式
  4. 接收服务端返回的数据

问题现象:

有时候发送数据的时候,该接口会被阻塞

问题解析:

1.当strResult 为空的时候,select 没有设置超时,这里会一直阻塞

根本原因:

为什么在这里select会一直阻塞?

是因为服务端没有返回数据到客户端,所以客户端就被一直阻塞了。

为什么服务端会没有数据返回?

除去服务端软件上的问题,还有一个原因是:因为使用的是本地回环,在一些嵌入式设备中,如果网卡驱动注册太慢,或者是没有注册网卡驱动,本地回环是不能工作的,所以服务端也就是会监听不到客户端的数据

对于这种情况,如果使用Unix domain socket(UDS) 就不会存在这样的问题。

(二)Unix domain socket(UDS)

UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC),它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。

UNIX Domain Socket有SOCK_DGRAM或SOCK_STREAM两种工作模式,类似于UDP和TCP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。

UNIX Domain Socket可用于两个没有亲缘关系的进程,是全双工的,是目前使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的。

工作流程

UNIX Domain socket与网络socket类似,可以与网络socket对比应用。

上述二者编程的不同如下:

  1. address family为AF_UNIX
  2. 因为应用于IPC,所以UNIXDomain socket不需要IP和端口,取而代之的是文件路径来表示“网络地址”。这点体现在下面两个方面。
  3. 地址格式不同,UNIXDomain socket用结构体sockaddr_un表示,是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。
  4. UNIX Domain Socket客户端一般要显式调用bind函数,而不象网络socket一样依赖系统自动分配的地址。客户端bind的socket文件名可以包含客户端的pid,这样服务器就可以区分不同的客户端。

​

---------------------------End---------------------------
长按识别二维码
关注 liwen01 公众号

unix domain 与本地本地回环在进程间通信中的差异的更多相关文章

  1. 基于libevent和unix domain socket的本地server

    https://www.pacificsimplicity.ca/blog/libevent-echo-server-tutorial 根据这一篇写一个最简单的demo.然后开始写client. cl ...

  2. Unix domain socket 简介

    Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信.socket 原本是为网络通讯设 ...

  3. 一个基于深度学习回环检测模块的简单双目 SLAM 系统

    转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12634631.html 写在前面 最近在搞本科毕设,关于基于深度学 ...

  4. 【转】PHP实现系统编程(四)--- 本地套接字(Unix Domain Socket)

    原文:http://blog.csdn.net/zhang197093/article/details/78143687?locationNum=6&fps=1 --------------- ...

  5. windows下使用wineshark分析抓取本地回环包

    ## 摘要 由于windows系统没有提供本地回环网络的接口,用Wireshark监控网络的话看不到localhost的流量. 想要获取本地的网络数据包,可以通过一款小巧的开源软件RawCap来进行抓 ...

  6. wineshark分析抓取本地回环包

    wineshark分析抓取本地回环包 摘要 由于windows系统没有提供本地回环网络的接口,用Wireshark监控网络的话看不到localhost的流量.想要获取本地的网络数据包,可以通过一款小巧 ...

  7. wireshark抓本地回环包

    问题描述: 在网络程序开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以 方法一:Wi ...

  8. wireshark抓取本地回环及其问题

    一:The NPF driver isn't running 这个错误是因为没有开启NPF服务造成的. NPF即网络数据包过滤器(Netgroup Packet Filter,NPF)是Winpcap ...

  9. RawCap抓取本地回环接口数据包

    RawCap.exe --help ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 D: ...

  10. CentOS 7添加本地回环地址

    CentOS 7添加本地回环地址 1. 临时添加ip addr add 10.10.1.1/32 dev lo:1重启失效2.永久添加cd /etc/sysconfig/network-scripts ...

随机推荐

  1. MyBatis高频面试题

    1.MyBatis中使用#和$书写占位符有什么区别? 2.Hibernate 与 Mybatis区别(MyBatis与Hibernate有什么不同). 3.持久层设计要考虑的问题有哪些? 4.你用过的 ...

  2. [VMware]ESXI下硬盘的两种直通方式

    文章来自:https://rmbz.net/archives/vmware-esxi-passthrough 最近再搞ESXI,把原来的"黑群晖"改成ESXI:因为群晖里有数据,为 ...

  3. window10 AppX Deployment Service (AppXSVC)占用大量内存导致资源管理器卡死无响应

    window10 AppX Deployment Service (AppXSVC)占用大量内存导致资源管理器卡死无响应,导致无法进入桌面打开软件等等. 1.打开任务管理的情况下,先结束卡死的资源管理 ...

  4. shared_ptr 自定义 deleter 删除器

    一些结论 如果 shared_ptr 管理的资源不是 new 分配的内存,才考虑自定义删除器,这也是为什么 make_shared 不支持自定义删除器的原因,因为 make_shared 就是通过 n ...

  5. vscode搜索卡顿

    解决vscode搜索,编辑器卡死问题

  6. 手把手带你通过API创建一个loT边缘应用

    摘要:使用API Arts&API Explorer调用IoT边缘服务接口创建应用,了解边缘计算在物联网行业的应用. 本文分享自华为云社区<使用API Arts&API Expl ...

  7. 【“互联网+”大赛华为云赛道】GaussDB命题攻略:支持三种开发语言,轻松完成数据库缓冲池

    摘要:七届中国国际"互联网+"大学生创新创业大赛火热报名中,为了帮助参赛者更好了解赛题设计思路和命题方向,华为云产业命题赛道举行了线上直播解读,华为云数据库资深架构师苏斌在直播间详 ...

  8. 教你如何用Keras搭建分类神经网络

    摘要:本文主要通过Keras实现了一个分类学习的案例,并详细介绍了MNIST手写体识别数据集. 本文分享自华为云社区<[Python人工智能] 十七.Keras搭建分类神经网络及MNIST数字图 ...

  9. 接通率维持 66% 以上,为什么火山引擎 VeDI 能让企业智能外呼不再难?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 智能机器人在企业级市场的应用更加深入了. 随着人工智能技术的进一步发展,包括智能外呼.财务审核.自助客服等在内的智 ...

  10. 【短道速滑四】Halcon的texture_laws算子自我研究

    Halcon里有个texture_laws 算子,最近实现了下,记录下相关细节. Halcon的文档里对该算子是这样描述的: texture_laws - Filter an image using ...