从上面的输出来看,.NET Core控制台应用启动时启动了多个线程,并在10、11、29、31号文件描述符启动了socket监听。那哪一个文件描述符监听的是5001端口呢。
shengjie@ubuntu:~/coding/dotnet/Io.Demo$ cat /proc/net/tcp | grep 1389 # 查看5001端口号相关的tcp链接(0x1389 为5001十六进制) 4: 0100007F:1389 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 43429 1 0000000000000000 100 0 0 10 0 12: 0100007F:9038 0100007F:1389 01 00000000:00000000 00:00000000 00000000 1000 0 44343 1 0000000000000000 20 4 30 10 -1 13: 0100007F:1389 0100007F:9038 01 00000000:00000000 00:00000000 00000000 1000 0 42149 1 0000000000000000 20 4 29 10 -1从中可以看到inode为[43429]的socket监听在5001端口号,所以可以找到上面的输出行lrwx------ 1 shengjie shengjie 64 5月 10 16:37 29 -> 'socket:[43429]',进而判断监听5001端口号socket对应的文件描述符为29。
当然,也可以从记录到strace目录的日志文件找到线索。在文中我们已经提及,socket服务端编程的一般流程,都要经过socket->bind->accept->read->write流程。所以可以通过抓取关键字,查看相关系统调用。
shengjie@ubuntu:~/coding/dotnet/Io.Demo$ grep 'bind' strace/ -rn strace/io.3696:4570:bind(10, {sa_family=AF_UNIX, sun_path="/tmp/dotnet-diagnostic-3696-327175-socket"}, 110) = 0 strace/io.3763:2241:bind(11, {sa_family=AF_UNIX, sun_path="/tmp/dotnet-diagnostic-3763-328365-socket"}, 110) = 0 strace/io.3763:2949:bind(29, {sa_family=AF_INET, sin_port=htons(5001), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 strace/io.3713:4634:bind(11, {sa_family=AF_UNIX, sun_path="/tmp/dotnet-diagnostic-3713-327405-socket"}, 110) = 0从上可知,在主线程也就是io.3763线程的系统调用文件中,将29号文件描述符与监听在127.0.0.1:5001的socket进行了绑定。同时也明白了.NET Core自动建立的另外2个socket是与diagnostic相关。
接下来咱们重点看下3763号线程产生的系统调用。
从中我们可以发现几个关键的系统调用:
socket
bind
listen
accept4
recvmsg
sendmsg
通过命令man命令可以查看下accept4和recvmsg系统调用的相关说明:
shengjie@ubuntu:~/coding/dotnet/Io.Demo/strace$ man accept4 If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. shengjie@ubuntu:~/coding/dotnet/Io.Demo/strace$ man recvmsg If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2))也就是说accept4和recvmsg是阻塞式系统调用。
验证I/O多路复用发起的系统调用同样以上面I/O多路复用的代码进行验证,验证步骤类似:
shengjie@ubuntu:~/coding/dotnet$ strace -ff -o Io.Demo/strace2/io dotnet run --project Io.Demo/ Press any key to start! 服务端已启动(127.0.0.1:5001)-等待连接... 127.0.0.1:37098-已连接 127.0.0.1:37098-接收数据:1 127.0.0.1:37098-接收数据:2 shengjie@ubuntu:~/coding/dotnet/Io.Demo$ nc localhost 5001 1 received:1 2 received:2 shengjie@ubuntu:/proc/2449$ netstat -natp | grep 5001 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 127.0.0.1:5001 0.0.0.0:* LISTEN 2449/Io.Demo tcp 0 0 127.0.0.1:5001 127.0.0.1:56296 ESTABLISHED 2449/Io.Demo tcp 0 0 127.0.0.1:56296 127.0.0.1:5001 ESTABLISHED 2499/nc shengjie@ubuntu:~/coding/dotnet/Io.Demo$ ps -h | grep dotnet 2400 pts/3 S+ 0:10 strace -ff -o ./Io.Demo/strace2/io dotnet run --project Io.Demo/ 2402 pts/3 Sl+ 0:01 dotnet run --project Io.Demo/ 2449 pts/3 Sl+ 0:00 /home/shengjie/coding/dotnet/Io.Demo/bin/Debug/netcoreapp3.0/Io.Demo 2516 pts/5 S+ 0:00 grep --color=auto dotnet shengjie@ubuntu:~/coding/dotnet/Io.Demo$ cd /proc/2449/ shengjie@ubuntu:/proc/2449$ ll task total 0 dr-xr-xr-x 11 shengjie shengjie 0 5月 10 22:15 ./ dr-xr-xr-x 9 shengjie shengjie 0 5月 10 22:15 ../ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2449/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2451/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2452/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2453/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2454/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2455/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2456/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2459/ dr-xr-xr-x 7 shengjie shengjie 0 5月 10 22:15 2462/ shengjie@ubuntu:/proc/2449$ ll fd total 0 dr-x------ 2 shengjie shengjie 0 5月 10 22:15 ./ dr-xr-xr-x 9 shengjie shengjie 0 5月 10 22:15 ../ lrwx------ 1 shengjie shengjie 64 5月 10 22:16 0 -> /dev/pts/3 lrwx------ 1 shengjie shengjie 64 5月 10 22:16 1 -> /dev/pts/3 lrwx------ 1 shengjie shengjie 64 5月 10 22:16 10 -> 'socket:[35001]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 100 -> /dev/random lrwx------ 1 shengjie shengjie 64 5月 10 22:16 11 -> 'socket:[34304]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 13 -> 'pipe:[31528]' l-wx------ 1 shengjie shengjie 64 5月 10 22:16 14 -> 'pipe:[31528]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 15 -> /home/shengjie/coding/dotnet/Io.Demo/bin/Debug/netcoreapp3.0/Io.Demo.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 16 -> /home/shengjie/coding/dotnet/Io.Demo/bin/Debug/netcoreapp3.0/Io.Demo.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 17 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Runtime.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 18 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Console.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 19 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Threading.dll lrwx------ 1 shengjie shengjie 64 5月 10 22:16 2 -> /dev/pts/3 lr-x------ 1 shengjie shengjie 64 5月 10 22:16 20 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Runtime.Extensions.dll lrwx------ 1 shengjie shengjie 64 5月 10 22:16 21 -> /dev/pts/3 lr-x------ 1 shengjie shengjie 64 5月 10 22:16 22 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Text.Encoding.Extensions.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 23 -> /dev/urandom lr-x------ 1 shengjie shengjie 64 5月 10 22:16 24 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Net.Sockets.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 25 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Net.Primitives.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 26 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/Microsoft.Win32.Primitives.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 27 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Diagnostics.Tracing.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 28 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Threading.Tasks.dll lrwx------ 1 shengjie shengjie 64 5月 10 22:16 29 -> 'socket:[31529]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 3 -> 'pipe:[32055]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 30 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Threading.ThreadPool.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 31 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Collections.Concurrent.dll lrwx------ 1 shengjie shengjie 64 5月 10 22:16 32 -> 'anon_inode:[eventpoll]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 33 -> 'pipe:[32059]' l-wx------ 1 shengjie shengjie 64 5月 10 22:16 34 -> 'pipe:[32059]' lrwx------ 1 shengjie shengjie 64 5月 10 22:16 35 -> 'socket:[35017]' lr-x------ 1 shengjie shengjie 64 5月 10 22:16 36 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Memory.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 37 -> /dev/urandom lr-x------ 1 shengjie shengjie 64 5月 10 22:16 38 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Diagnostics.Debug.dll l-wx------ 1 shengjie shengjie 64 5月 10 22:16 4 -> 'pipe:[32055]' lrwx------ 1 shengjie shengjie 64 5月 10 22:16 5 -> /dev/pts/3 lrwx------ 1 shengjie shengjie 64 5月 10 22:16 6 -> /dev/pts/3 lrwx------ 1 shengjie shengjie 64 5月 10 22:16 7 -> /dev/pts/3 lr-x------ 1 shengjie shengjie 64 5月 10 22:16 9 -> /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0/System.Private.CoreLib.dll lr-x------ 1 shengjie shengjie 64 5月 10 22:16 99 -> /dev/urandom shengjie@ubuntu:/proc/2449$ cat /proc/net/tcp | grep 1389 0: 0100007F:1389 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 31529 1 0000000000000000 100 0 0 10 0 8: 0100007F:1389 0100007F:DBE8 01 00000000:00000000 00:00000000 00000000 1000 0 35017 1 0000000000000000 20 4 29 10 -1 12: 0100007F:DBE8 0100007F:1389 01 00000000:00000000 00:00000000 00000000 1000 0 28496 1 0000000000000000 20 4 30 10 -1