简谈端口号
如果说ip可以用来标识一个网卡,那么端口是不能单独说的,单独端口没有意义,端口一定是和其他属性一起组成元组来标识一个套接字,如udp套接字,是无连接的,因此只要用 {ip,端口,协议}三元组,就可以标识udp套接字
端口号范围划分
端口号是一个二字节的整数,其范围就是0~65535
知名端口号
UDP 协议格式
1.udp报头的长度是固定长度8字节,4字节一行,那就是两行
2.源端口、目的端口四个字节,无需多言。
3.两字节的udp报文长度,这个字段挺重要,我们使用recvfrom,其函数底层会从udp接收缓冲区中读出一个udp报文,就是靠的这个字段,先读出8字节的udp报头,再根据报头中的udp报文长度字段,来直接读出一个完整udp报文。
4.udp层将udp报文中除了校验和这两字节外的剩下全部内容使用摘要算法,得到两字节的校验和,这个字段用来判断报文有没有出错
UDP 的特点
1.无连接:使用udp协议,那么在sendto发送消息和recvfrom接收消息时都需要显式的提供或接收对端地址,因为默认情况下是不知道对端套接字地址是什么的,udp套接字是用三元组{本地ip,本地port,协议}来表示的,这就是对无连接的理解
2.不可靠:没有超时重传和确认应答机制,报文丢了也不知道,也不管
3.面向数据报:udp没有发送缓冲区,发送数据直接走协议栈,不会像tcp一样等到满足条件才开始组装报文,udp有接收缓冲区,其接收缓冲区里是udp报文,recvfrom底层会从接收缓冲区中读出一个完整udp报文,然后去掉udp报头,将有效载荷写进recvfrom参数提供的缓冲区中
UDP的缓冲区
1.udp没有发送缓冲区,调用sendto后,触发软中断,cpu陷入内核,执行中断方法走协议栈,会将sendto参数传的数据拷贝然后加上udp报头,然后传给ip层,....,也就是说udp发送数据是不进行缓冲的,直接就开始封装报文发出去
2.udp有接收缓冲区,网卡收到消息后写进网卡接收缓冲区然后触发硬件中断走协议栈,最后到了传输层,会通过三元组找到套接字,将udp报文写进udp套接字的接收缓冲区中,并唤醒在接收缓冲区等待队列上的进程,然后recvfrom会从udp接收缓冲区读出来一个udp报文,去掉报头,将有效载荷写进recvfrom参数的缓冲区里
3.udp套接字既能读也能写,所以是全双工的
udp使用注意
udp报头中的两字节报文长度限制了udp报文最大就是65535字节,所以如果要传输的数据过大,那就得自个应用层分好,然后sendto发出去,到时候recvfrom接收到了多段数据,还得自个应用层拼好