《TCP/IP网络编程》第5章 基于TCP的服务器端/客户端(2)
5.1 回声客户端的完美实现
1. 回声服务器端没有问题,只有客户端有问题。
回声客户端传输的是字符串,而且是通过调用write函数一次性发送的,之后还调用一次read函数,期待着接收自己传输的字符串。
2. 回声客户端问题解决方法
解决:因为可以提前确定接收数据的大小,若之前传输了20字节长的字符串,则在接收时循环调用read函数读取20个字节即可。
3. 如果问题不在于回声客户端:定义应用层协议
由于回声客户端已知需要接收数据的长度,所以问题容易解决,但是如果无法提前预知需要接收数据长度,该如何?此时需要应用层协议的定义。
服务器端/客户端实现过程中逐步定义的这些规则几何就是应用层协议。可以看出,应用层协议并不是高深莫测的存在,只不过是为特定程序的实现而制定的规则。
4. 实现计算器服务器端/客户端示例(设计应用层协议)
操作如下所示:
编写程序前,设计如下应用层协议:
- 客户端连接到服务器端之后以1字节整数形式传递待算数字个数;
- 客户端向服务器端传递的每个整数型数据占用4字节;
- 传递整数型数据后接着传递运算符。运算符信息占用1字节;
- 选择字符+、-、*之一传递;
- 服务器端以4字节整数型向客户端传回运算结果;
- 客户端得到运算结果后终止与服务器端的连接;
若想在同一数组中保存并传输多种数据类型,应把数组声明为char类型,而且需要额外做一些指针及数组运算。
5.2 TCP原理
1. TCP套接字中的I/O缓冲
服务器端即使调用1次write函数传输40字节的数据,客户端也有可能通过4次read函数调用每次读取10字节。
实际上,write函数调用后并非立即传输数据,read函数调用后也并非马上接收数据。
这些I/O缓冲特性如下:
- I/O缓冲在每个套接字中单独存在;
- I/O缓冲在创建套接字时自动生成;
- 即使关闭套接字也会继续传递输出缓冲中遗留的数据;
- 关闭套接字将丢失输入缓冲的数据;
TCP会控制数据流,TCP中有滑动窗口协议(SlidingWindow)协议。
write函数和Windows的send函数并不会在完成向对方主机的数据传输时返回,而是在数据移到输出缓冲时。但TCP会保证对输出缓冲数据的传输,所以write函数在数据传输完成时返回。
2. TCP内部工作原理1:与对方套接字的连接
Three-way handshaking(三次握手):
3. TCP内部工作原理2:与对方主机的数据交换
ACK号—> SEQ号 + 传递的字节数 + 1 ,告知对方下次要传递的SEQ号。
4. TCP的内部工作原理3:断开与套接字的连接
双方断开连接的过程又称四次握手(Four-wayhandshaking)。