前言:

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. ElasticSearch之Index modules

    索引的参数,分为两类: 静态参数,仅支持在创建索引时指定,或者关闭索引后指定. 动态参数,允许在索引工作期间指定或者修改. 静态参数 index.number_of_shards 默认值为1. 本参数 ...

  2. DVWA File Upload(文件上传)全等级

    File Upload(文件上传) 目录: File Upload(文件上传) 一句话木马的构成 1. Low 1.上传一句话木马1.php 2.中国蚁剑 2.Medium 3. High 4.Imp ...

  3. [活动(深圳)] .NET Love AI 之 .NET Conf China 2023 Party 深圳

    中国.NET 社区2023年12月16日 在北京成功举办了.NET Conf China 2023,虽然北京飘起雪,依然挡不住想要参加活动的全国各地的.NET开发兄弟姐妹的热情.大家可以通过大会精彩照 ...

  4. 拥抱Serverless释放生产力,探索华为云Serverless车联网最佳实践

    华为云Serverless车联网场景解决方案,以FunctionGraph为核心的Serverless化组合方案,使用FunctionGraph.OBS.DIS等技术,可以实现架构的灵活扩展,在出行高 ...

  5. Xml Entity 实体互转(JAXB)

    感觉比 xStream 操作起来复杂些 Xml Entity 实体互转(XStream).但学习成本低些,不需要引用第三方依赖包 需要注意的是 实体中如果加了 getXX 需要在上面加上 @XmlTr ...

  6. 压测工具 Locust

    一.认识Locust 定义 Locust是一款易于使用的分布式负载测试工具,完全基于事件,即一个locust节点也可以在一个进程中支持数千并发用户,不使用回调,通过gevent使用轻量级过程(即在自己 ...

  7. AIGC加速迭代,云栖大会视频云「媒体服务」专场与你共话云智深度融合

    2023杭州·云栖大会 倒计时5天! 阿里云视频云 5大并行Session 11场话题演讲 深度演绎云智融合的全面进化 「媒体服务」Tech专场 重磅议题剧透来袭 01 「媒体服务」Tech • 新数 ...

  8. COOIS增强

    一.订单抬头增强 二.结构添加字段 添加ZGCWL字段 三.BADI增强 四.其他界面增强 不同的界面,选择不同的修改结构 抬头 ct_ioheader 组件 ct_ioopcomp 工序 ct_io ...

  9. 前端知识点 | 查看已登录网站 Cookie 信息

    方法一:针对 Chrome 浏览器 设置 \(\to\) 隐私设置和安全性 \(\to\) Cookie 及其他网站数据 \(\to\) 查看所有 Cookie 和网站数据 or chrome://s ...

  10. 3.1 《数据库系统概论》SQL概述及数据定义(模式SCHEMA、表TABLE、索引INDEX)

    前言 本篇文章学习书籍:<数据库系统概论>第5版 王珊 萨师煊编著 视频资源来自:数据库系统概论完整版(基础篇+高级篇+新技术篇) 由于 BitHachi 学长已经系统的整理过本书了,我在 ...