一、套接字
1、面向连接的套接字
传输特点:
- 传输过程中数据不会消失。
- 按序传输数据。
- 传输的数据不存在数据边界。
- 套接字连接必须一一对应(若要向10个客户端套接字提供服务,则除了守门的服务器套接字外,还需要10个服务器端套接字)。
收发数据的套接字内部有缓冲,简而言之就是字节数组。通过套接字传输的数据将保存到该数组。因此,收发数据并不意味着马上调用read函数。只要不超过数组容量,则有可能在数据填充满缓冲后通过一次read函数调用读取全部,也有可能分成多次read函数调用进行读取。也就是说,在面向连接的套接字中,read函数和write函数的调用次数并无太大意义。
套接字缓冲已满不意味着数据丢失:如果read函数读取速度比接收数据的速度慢,则缓冲有可能被填满。此时,套接字无法再接收数据,但即使这样也不会发生数据丢失,因为传输端套接字将停止传输。即,面向连接的套接字会根据接收端的状态传输数据,如果传输出错还会提供重传服务。
2、面向消息的套接字
传输特点:
- 强调快速传输而非传输顺序。
- 传输的数据可能丢失也可能损毁。
- 传输的数据有数据边界,即接收数据的次数和传输次数相同。
- 限制每次传输的数据大小。
二、TCP原理
1、TCP套接字中的I/O缓冲
实际上,write函数调用后并非立即传输数据,read函数调用后也并非马上接收数据。更准确地说,write函数调用瞬间,数据将移至输出缓冲;read函数调用瞬间,从输入缓冲读取数据。
I/O缓冲特性如下:
- I/O缓冲在每个TCP套接字中单独存在。
- I/O缓冲在创建套接字时自动生成。
- 即使关闭套接字也会继续传递输出缓冲中遗留的数据。
- 关闭套接字将丢失输入缓冲中的数据。
2、TCP的半关闭
一旦两台主机间建立了套接字连接,每个主机就会拥有单独的输入流和输出流。其中一个主机的输入流与另一台主机的输出流相连,而输出流则与另一主机的输入流相连。
半关闭指断开其中一个流,而非同时断开两个流。用于半关闭的函数是shutdown函数。
若只断开输入流,则套接字无法接收数据。即使输入缓冲收到数据也会抹去,而且无法调用输入相关函数。
若只断开输出流,则套接字无法传输数据。但是如果输出缓冲还留有未传输的数据,则将传递至目标主机。
断开输出流时向对方主机传输EOF。调用close函数的时候会同时关闭I/O流,这样也会向对方发送EOF。
三、UDP原理
UDP中的服务器端和客户端没有连接。UCP中只有创建套接字的过程和数据交换过程。
在UDP中,不管是服务器端还是客户端都只需要1个套接字。