一、使用wireshark抓包分析协议头

(一)wireshark常用的过滤语句

tcp.port == <想要查看的端口号>
ip.src == <想要查看的源IP地址>
ip.dest == <想要查看的目的IP地址>
ip.addr == <想要查看的IP地址>

(二)抓包分析

1. 链路层

网络编程(四)-LMLPHP

使用了以太网头(MAC头)
网络编程(四)-LMLPHP
传统的交换机工作在链路层,根据目的mac地址决定如何转发消息;
(内部维护接口和mac地址的映射表)

目的mac地址:接收方的mac地址
源mac地址:发送方的mac地址
类型:后面使用的协议的类型

(二)网络层

IP头
网络编程(四)-LMLPHP
路由器工作在网络层,根据IP地址决定如何转发

(三)传输层

端口号的范围被协议限制
网络编程(四)-LMLPHP

(四)应用层

二、TCP的三次握手和四次挥手

(一)三次握手

由客户端发起
序列号本身是一个随机值(0-4字节)

有序的

(二)四次挥手

由主动关闭方发起,一般是由客户端发起

超时重发,
快速重发,

累计确认:回复连续的包的确认
滑动窗口

流量控制

三、TCP和UDP比较总结

(一) TCP网络编程

1.客户端一般不需要绑定自己的网络信息结构体
因为操作系统会自动给客户端的ip地址和端口号赋值,也方便用户操作。
如果想要手动指定,也可以,需要调用bind()函数即可。

2.服务器端accept函数的后两个参数即使设置成NULL,服务器也可以给客户端回复消息,原因是,服务器侧不是依赖于手动给定的IP地址和端口号来联系客户端的,而是给每个客户端都分配一个独立的文件描述符 acceptfd,来专门用于和该客户端通信,
也就是说TCP的服务器,acceptfd和客户端是一一对应的关系。

3.TCP网络编程中可以使用 read/write send/recv sendto/recvfrom 来收发数据。

4.服务器端的accept函数本质就是一个阻塞的读函数,也就是一个接收函数,
客户端的connect函数本质就是个写函数,也就是一个发送函数,
收发的数据本质就是客户端的网络信息结构体。

5.TCP的服务器默认的是一个循环服务器,没法同时处理多个客户端的请求,
原因是tcp的服务器有两个阻塞函数 accept 和 recv,两个函数之间相互会有影响。
可以使用 多进程 多线程 IO多路复用 来解决。

(二)UDP网络编程

1.UDP是无连接的,但是也可以双向的收发数据
因为UDP使用的是 sendto/recvfrom 来收发数据,sendto时可以指定接收方的信息。
sendto函数相当于 send函数和 connect函数的二合一
recvfrom函数相当于 recv函数和 accept函数的二合一

2.UDP中客户端也可以使用 connect 函数先将服务器的信息缓存在自己的内核中,
然后就可以使用 send 和 recv 收发数据了。

3.如果UDP服务器端的recvfrom函数的后两个参数设置成 NULL了,那么接收数据是没有问题的,但是就没法给发送方回信了,因为sendto的后两个参数没法填写。

4.UDP服务器默认的就是一个并发服务器,因为只有一个阻塞的函数 recvfrom。

06-15 14:07