AF_UNIX

AF_UNIX 用于本地,通过socket文件通信 , 不用经过cpu对包解析,放到网卡, 内核直接放到对应的socket缓冲文件。如果客户端与服务端通过socket文件通信,那通过netstat命令, 能找到客户端与服务端的连接关系吗?
请看测试实例:

server.pl

#! /usr/bin/perl -wuse strict;
use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN );my $SOCK_PATH = '/tmp/test.sock';
unlink($SOCK_PATH) if -e $SOCK_PATH;my $server = IO::Socket::UNIX->new(Type => SOCK_STREAM(),Local => $SOCK_PATH,Listen => SOMAXCONN,
)or die("Can't create server socket: $!\n");while (1) {my $connection = $server->accept;if (fork() == 0) {print "** New connection received **\n";$connection->autoflush(1);my $count = 1;while (my $line = <$connection>) {if ($line){chomp($line);$connection->print($count . ' -> ' . $line . "\n"); print "Received and replied to $count '$line'\n";$count++;}}close $connection;exit;}
}

client.pl

#!/usr/bin/perl -wuse strict;
use IO::Socket::UNIX qw( SOCK_STREAM );my $SOCK_PATH = '/tmp/test.sock';
my $client = IO::Socket::UNIX->new(Type => SOCK_STREAM(),Peer => $SOCK_PATH
)or die("Can't connect to server: $!\n");$client->autoflush(1);## Listen for replies
if (fork() == 0) {while (my $line = <$client>) {if ($line){chomp($line);print("Recv: '" . $line . "'\n");}}
}## Send something
while(1){for my $itm ('Alpha','Beta','Gamma','Delta'){print("Send: " . $itm . "\n");print($client $itm . "\n") or warn("Can't send: $!\n"); # send to server, \n terminates}sleep 5
}print "** Client Finished **\n";

通过lsof netstat 查找客户端连接的socket文件

查看进程id

[root@localhost ~]# ps auxf | grep server.pl
root      19083  0.0  0.1 135592  4324 pts/1    S+   19:18   0:00  |       \_ perl server.pl
root      19092  0.0  0.1 135592  2700 pts/1    S+   19:18   0:00  |           \_ perl server.pl
root      19157  0.0  0.0 112708   984 pts/3    S+   19:18   0:00          \_ grep --color=auto server.pl
[root@localhost ~]# ps auxf | grep client.pl
root      19090  0.0  0.1 135592  4308 pts/2    S+   19:18   0:00  |       \_ perl client.pl
root      19091  0.0  0.0 135592  2344 pts/2    S+   19:18   0:00  |           \_ perl client.pl
root      19211  0.0  0.0 112708   984 pts/3    S+   19:19   0:00  |       \_ grep --color=auto client.pl

查看服务端文件占用

[root@localhost ~]# lsof -p 19092 | grep sock
perl    19092 root    3u  unix 0xffff93dbd27ba400       0t0    70144 /tmp/test.sock
perl    19092 root    4u  unix 0xffff93dbd1ee5800       0t0    70145 /tmp/test.sock
[root@localhost ~]# netstat -anlp | grep 19092
unix  3      [ ]         STREAM     CONNECTED     70145    19092/perl           /tmp/test.sock

查看客户端文件占用

[root@localhost ~]# lsof -p 19090 |grep sock
perl    19090 root    3u  unix 0xffff93dbd1ee3c00       0t0    70162 socket
[root@localhost ~]# lsof -p 19091 |grep sock
perl    19091 root    3u  unix 0xffff93dbd1ee3c00       0t0    70162 socket[root@localhost ~]# netstat -anlp | grep 19090
unix  3      [ ]         STREAM     CONNECTED     70162    19090/perl
[root@localhost ~]# netstat -anlp | grep 19091
[root@localhost ~]# [root@localhost ~]# ll /proc/19090/fd/
total 0
lrwx------. 1 root root 64 Apr 27 19:21 0 -> /dev/pts/2
lrwx------. 1 root root 64 Apr 27 19:21 1 -> /dev/pts/2
lrwx------. 1 root root 64 Apr 27 19:18 2 -> /dev/pts/2
lrwx------. 1 root root 64 Apr 27 19:21 3 -> socket:[70162]

通过以上几种方法查看客户端的情况, 我们只知道它有建立一个socket连接,但是具体连接到那个socket文件,并不知道。那根据lsof 输出的 device=0xffff93dbd1ee3c00, 以及node=70162, 能找到对应的socket文件吗?

[root@localhost ~]# stat /tmp/test.sock File: ‘/tmp/test.sock’Size: 0           Blocks: 0          IO Block: 4096   socket
Device: fd00h/64768d    Inode: 67785956    Links: 1
Access: (0755/srwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:user_tmp_t:s0
Access: 2020-04-27 19:18:33.922022962 +0800
Modify: 2020-04-27 19:18:28.245022727 +0800
Change: 2020-04-27 19:18:28.245022727 +0800Birth: -
[root@localhost ~]#

发现实际 /tmp/test.sock 的inode是67785956 显然这俩不是一个概念。
继续看,0xffff93dbd1ee3c00应该是一个内存地址,那我们在proc下找找。

[root@localhost ~]# grep -Irn  "ffff93dbd1ee3c0" /proc/net
/proc/net/unix:80:ffff93dbd1ee3c00: 00000003 00000000 00000000 0001 03 70162

也看不出具体是那个文件(但对于如tcp连接,其实在/proc/net/tcp中是可以找到连接的 ip:port 信息的)

那要怎么才能找对对应连接的socket文件呢,
最后还是在外文上找到了资料,https://unix.stackexchange.com/questions/16300/whos-got-the-other-end-of-this-unix-socketpair/190606#190606

通过ss命令或打印peer值

ss命令

对于内核大于3.3, 可以使用ss命令

[root@localhost ~]# ss | grep 70162
u_str  ESTAB      0      0       * 70162                 * 70145
u_str  ESTAB      0      0      /tmp/test.sock 70145                 * 70162
[root@localhost ~]#

70162在ss命令种,表示Port, 在netstat种又表示 I-Node, 有什么不一样吗?

打印peer内存地址

对于没有ss命令的环境,则可以从上述的内存地址找到答案。即 0xffff93dbd1ee3c00
利用之前一篇博客搭建的内核调试环境,参见: https://www.jianshu.com/p/caff00d28b5e

这次我们使用kcore来查看内核的当前运行情况

gdb /usr/lib/debug/lib/modules/3.10.0-957.el7.x86_64/vmlinux /proc/kcore
Core was generated by `BOOT_IMAGE=/vmlinuz-3.10.0-957.el7.x86_64 root=/dev/mapper/centos-root ro crashk'.
#0  0x0000000000000000 in irq_stack_union ()
(gdb) print ((struct unix_sock*) 0xffff93dbd1ee3c00)->peer
$1 = (struct sock *) 0xffff93dbd1ee5800
(gdb) quit
[root@localhost ~]# lsof  | grep 0xffff93dbd1ee5800
perl      19092                 root    4u     unix 0xffff93dbd1ee5800       0t0      70145 /tmp/test.sock
[root@localhost ~]#

Linux内核关于unix_sock的定义

/* The AF_UNIX socket */
struct unix_sock {/* WARNING: sk has to be the first member */struct sock       sk;struct unix_address     *addr;struct path        path;struct mutex       readlock;struct sock        *peer;struct list_head  link;atomic_long_t      inflight;spinlock_t     lock;unsigned char      recursion_level;unsigned long       gc_flags;
#define UNIX_GC_CANDIDATE   0
#define UNIX_GC_MAYBE_CYCLE 1struct socket_wq   peer_wq;wait_queue_t        peer_wake;
};

与我们的客户端代码是一致的

my $client = IO::Socket::UNIX->new(
Type => SOCK_STREAM(),
Peer => $SOCK_PATH
)or die("Can't connect to server: $!\n");

该方法即将peer的内存地址打印出来,对应的就是path信息了。 有了这些排查方法,我们就能找到client连接的是哪个socket文件以及服务端进程, 方便定位问题。

linux socket pair相关推荐

  1. Linux Socket编程入门——浅显易懂

    文章目录 1. 概述 2. Socket 3. 网络字节序 4. sockaddr 数据结构 5. 网络套接字API函数  5.1 socket()  5.2 bind()  5.3 listen() ...

  2. Linux Socket基础介绍

    Linux Socket函数库是从Berkeley大学开发的BSD UNIX系统中移植过来的.BSD Socket接口是众多Unix系统中被广泛支持的TCP/IP通信接口,Linux下的Socket程 ...

  3. python封装api linux_python Socket编程-python API 与 Linux Socket API之间的关系

    python socket编程 by SA19225409 地址协议家族 Python 支持 AF_UNIX. AF_NETLINK. AF_TIPC 和 AF_INET 家族 AF_UNIX 基于本 ...

  4. linux socket关闭连接 shutdown与close

    在Linux socket关闭连接的方法有两种分别是shutdown和close,首先看一下shutdown的定义 #include<sys/socket.h>int shutdown(i ...

  5. Linux socket关闭连接shutdown与close

    在Linux socket关闭连接的方法有两种分别是shutdown和close,首先看一下shutdown的定义 #include<sys/socket.h> int shutdown( ...

  6. linux socket使用情况 ss -s ss -t -a | cat /proc/net/socketstat

    linux socket使用情况 ss -s ss -t -a | cat /proc/net/socketstat Linux系统中,查看SOCKET使用情况可以使用ss命令. 1.命令格式: ss ...

  7. 对于linux socket与epoll配合相关的一些心得记录

    对于linux socket与epoll配合相关的一些心得记录 没有多少高深的东西,全当记录,虽然简单,但是没有做过测试还是挺容易让人糊涂的 int nRecvBuf=32*1024;//设置为32K ...

  8. linux 查看socket fd,linux socket中select()函数以及FD_ZERO FD_SET FD_CLR FD_ISSET

    linux socket非阻塞编程时常见到如下的code: socket   s; ..... fd_set   set; ..... struct timeval tv; while(1) { FD ...

  9. linux socket高性能服务器处理框架

    这个博客很多东西 http://blog.csdn.net/luozhonghua2014/article/details/37041765 思考一种高性能的服务器处理框架 1.首先需要一个内存池,目 ...

最新文章

  1. 科学家研究:生女有撇步 多钙少碰香蕉
  2. 前端笔记-使用vue-cli(脚手架)开发TodoList
  3. 排序算法比较以及代码展示
  4. 电脑显示器尽快触摸化
  5. 当深度学习遇见自动文本摘要
  6. 小技巧 - 同步苹果手机和 Windows 的提醒事项
  7. Layui多文件上传,java后台(servlet实现)
  8. 【采样算法】拉丁超立方采样
  9. Tower of Hanoi(汉诺塔)详解
  10. mt6737电池状态监测
  11. sql server中的怎么把数值型转换为字符串
  12. cad画不规则实体_如何在CAD中徒手画不规则的图形
  13. 计算机类部队文职好考吗,“军队文职”招考遇冷,8000余岗位无人报考,是铁饭碗不香了吗...
  14. RM电控(更新中……
  15. 基于java前行国家公务员模拟笔试系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  16. 公司如何选择适合的管理软件?
  17. android三国2,三国群英传2威力加强版安卓
  18. Windows动态库注册和取消注册
  19. 根据LabelImg标注的方框大小批量裁剪图片
  20. matlab绘图(学习中)

热门文章

  1. 2021年山东省安全员B证考试题及山东省安全员B证找解析
  2. 拥抱Transformer,图解NLP处理流程四部曲
  3. 【Web_UI自动化_Python3_12306查询余票/车次_seleniumkeysselectXpath定位】12306火车票官方订票网站,查询余票/车次,自动化测试案例
  4. 第一个Python代码-猜数字
  5. 中谷教育python精讲_中谷教育Python视频(课件、源码)推荐
  6. 使input文本框中文字居中
  7. mysql函数临时表_MySQL函数中创建临时表
  8. xshell连接不了服务器显示22端口,解决Xshell不从22端口连接服务器
  9. 罗永浩宣布退网创业;谷歌研究员“走火入魔”事件曝光:认为AI已具备人格,被罚带薪休假;Wasmer 2.3 发布|极客头条
  10. SpringCloud(下)