栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

深入理解socket——在本地实现一次收发网络包

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深入理解socket——在本地实现一次收发网络包

首先需要得到本地IP地址

或者通过回环地址127.0.0.1

linux 通过ip adder 查看 ip地址为172.26.96.233

新建进程1(服务端)

nc -l 本地ip 端口号   启动本地服务端 172.26.96.233的9090端口开启监听

此时出现阻塞等待连接

新建进程2(查看当前连接状态)

netstat -natp  显示连接

可以看到第三行程序nc

172.26.96.233:9090为LISTEN监听状态,        0.0.0.0:*

表示接收到

目的地址为172.26.96.233端口为9090   

源地址为任何ip地址和端口

的数据包,就把数据包交给nc程序

外界来的数据包通过四元组匹配Socket,从而将数据包交给正确的服务

 Recv-Q接收队列   Send-Q发送队列

现在该服务端处于监听状态,还未进行三次握手

一旦有客户端建立连接,才会开始三次三次握手

新建进程3(用于抓包)  过滤端口号为9090

tcpdump -nn -i eth0 port 9090

 这里命令写错了,应该改为tcpdump -nn -i lo port 9090  (走本地环回地址而没有走网卡)

新建进程4.(作为用户进程),连接该ip地址和端口号

 或者用telnet

此时进程3抓到包

  • SYN
  • SYN+ACK
  • ACK

[S.]   SYN

[.]   ACK

并且此时新增ESTABLISH状态的连接

新增

lo:9090(服务端) ->lo 48388(客户端)

lo 48388(客户端) ->lo 9090 (服务端)

只要是连接,都会有自己独立的队列,不能进行共享不然区别不出队列中某条数据是谁发的

 

客户端给服务端发送消息的过程:

进程4(用户进程)给服务端发送消息 

进程1(服务进程)收到消息

此时进程3抓到的包

客户端发送数据包 length=6  hello 5个字符+换行符=6个字节

由于TCP是可靠传输的,服务端回传一个ACK表示收到

在这个过程中,客户端send-Q把数据发出去,发到对方的receive-Q,对方从接收队列中读取

服务端给客户端发送消息的过程

进程1(服务端)给进程4(客户端)发送消息 

进程4(客户端)收到进程1(服务端发来的消息)

 这个过程中进程3抓到的包

 服务端发送数据包 length=6  hello client12个字符+换行符=13个字节

由于TCP是可靠传输的,客户端回传一个ACK表示收到

在这个过程中,服务端send-Q把数据发出去,发到对方的recv-Q,对方从接收队列中读取

  • socket本身用4元组(源IP,源端口,目的IP,目的端口)唯一区分,真正的数据传输靠socket自己独立的发送和接收队列完成
  • 三次握手实际是双方开辟资源,产生为对方提供服务的队列以及规则,未来的数据包在上面进行发送和接受
  • 在刚三次握手时队列就可以使用,但三次握手完成后队列才真正能够使用(Socket处于ESTABLISHED)

一个主机端口号有65535个

理论上服务器一个端口号最多可以建立65536个连接

 

 无状态协议

客户端服务端通信,必须通过TCP协议建立socket连接

如果只建立一个连接,但是有很多线程 如果应用层使用HTTP传输 如果多个线程使用同一连接,返回消息时无法区分返回给哪个线程,所以 HTTP协议是无状态的,一个线程只能同时使用一个连接 如果要满足多个线程和服务器同时通信,必须建立多个连接

短连接与长连接:

短连接:

单步请求(发送完回来,后面发不发不重要,完全可以断开)

长连接:

设置为KEEPALIVE开启,一个连接串行请求资源

有状态通信:

RPC协议给消息设置id,通过map进行映射,消息返回时可以匹配线程

约束:必须完成id的返回

请求方 对不同服务,控制连接池数量

服务提供方 限制链接数量,限流

TCP连接建立后,因为各种原因断开了,假设是client侧网络断了,那么服务端端侧连接没有关闭,若client再次发起请求,又建立TCP,之前连接的服务端为什么不能立即释放socket队列等待资源?

连接是两个端点间的队列,中间断了,两边都不知道谁断了,客户端发了几次后发现没有回应,客户端连接断开。

服务端是无法感知到的,在加上服务端没有开启 TCP keepalive,又没有数据交互的情况下,服务端的 TCP 连接将会一直处于 ESTABLISHED 连接状态,直到服务端重启进程

解决方法:内核中有心跳机制,服务端需要利用心跳机制进行断开

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/945954.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号