TCP/IP网络编程 | notes
2022-10-14 14:10:37
本文总阅读量次
基于TCP
服务端
- socket() 创建一个socket,用于传输数据。
- bind() 为socket分配ip地址和端口号。
- listen() 将socket设置为可接受连接。
- accept() 当客户端发起连接时,处理请求;若无,则一直阻塞在这里。
- read() or write() 具体连接后的业务。
- close() 断开连接。
- 函数返回一个sockfd,与操作文件时的fd相同(linux中)。
- 网络地址+主机地址,路由器和交换机,大小端。
- 服务端中开始创建的socket,用来处理客户端的连接请求;而后来通过accept创建的socket才是真正用于客户端与服务端的通信,类似于netty中boss和worker?
客户端
- socket()
- connect()
- read() or write()
- close()
习题
三次握手过程
建立连接(三次握手)
传递的数据包中有SEQ(Sequence number),ACK(Acknowledge,用于确认是否收到)。
- 主机A向B发送了[SEQ: 1000, ACK: -],表明:我已经向你发送了序列号为1000的数据包,如果收到了,请通知我给你发送1001的数据包。
- 主机B向A发送了[SEQ: 2000, ACK: 1001],表明:我已经向你发送了序列号为2000的数据包,如果收到了,请通知我给你发送2001的数据包;刚才你发送的1000我以及收到了,请发送1001。
- 主机A向B发送了[SEQ: 1001, ACK: 2001],表明:同理。
为什么一定需要三次?
问题本质是,需要建立连接的双方最少需要几次消息传输,才能在一个不可靠的信道中,确认连接。
- 0次,显然不成立。
- 1次,A向B发送,但是A不知道B是否接收到。
- 2次,A向B发送,B确认收到,B再向A发送,但是B不知道A是否接收到。
传输数据
建立连接之后:
- 主机A向B发送了[SEQ: 1200, data: 100Byte],表明发送了1200,若收到了,请通知我给你发送1301。
- 主机B向A发送了[ACK: 1301]。若收到的ACK小于1301,说明丢失了部分数据,可能需要重发?
断开连接
- A向B发送“断开连接的消息”。此时说明A不会再发送数据,但不代表不接收数据,因为A无法控制B发不发送。
- B向A发送”收到A发来的断开连接的消息“,目的是让A知道我已经收到了,防止A一直发。因为这个时候可能B还要向A一直发送数据。
- B向A发送“数据已经发送完了”,可以断开连接。
- A向B发送“收到”,断开连接。
如何保证可靠
通过ACK=SEQ+len(data)+1来保证
对方输入缓冲区的大小,小于需要write的大小,TCP会如何处理
write的数据不会超过buffer
基于UDP
客户端/服务端
- sendto()
- recvfrom()