Merge pull request #11 from shangguanyongshi/master

修改部分错字和表述
This commit is contained in:
riba2534
2022-07-04 21:09:40 +08:00
committed by GitHub
4 changed files with 10 additions and 10 deletions

View File

@@ -83,13 +83,13 @@ socket 函数的第三个参数决定最终采用的协议。前面已经通过
> 可以应对同一协议族中存在的多个数据传输方式相同的协议,所以数据传输方式相同,但是协议不同,需要用第三个参数指定具体的协议信息。
本书用的是 Ipv4 的协议族,和面向连接的数据传输,满足这两个条件的协议只有 TPPROTO_TCP ,因此可以如下调用 socket 函数创建套接字,这种套接字称为 TCP 套接字。
本书用的是 Ipv4 的协议族,和面向连接的数据传输,满足这两个条件的协议只有 IPPROTO_TCP ,因此可以如下调用 socket 函数创建套接字,这种套接字称为 TCP 套接字。
```c
int tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
```
SOCK_DGRAM 指的是面向消息的数据传输方式,满足上述条件的协议只有 TPPROTO_UDP 。这种套接字称为 UDP 套接字:
SOCK_DGRAM 指的是面向消息的数据传输方式,满足上述条件的协议只有 IPPROTO_UDP 。这种套接字称为 UDP 套接字:
```c
int udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

View File

@@ -359,7 +359,7 @@ Network ordered integer addr: 0x4f7ce87f
```c
#include <arpa/inet.h>
char *inet_ntoa(struct in_addr adr);
//成功时返回保存转换结果的字符串地址值,失败时返回-1
//成功时返回保存转换结果的字符串地址值,失败时返回 NULL 空指针
```
该函数将通过参数传入的整数型IP地址转换为字符串格式并返回。但要小心返回值为 char 指针,返回字符串地址意味着字符串已经保存在内存空间,但是该函数未向程序员要求分配内存,而是再内部申请了内存保存了字符串。也就是说调用了该函数后要立即把信息复制到其他内存空间。因为,若再次调用 inet_ntoa 函数,则有可能覆盖之前保存的字符串信息。总之,再次调用 inet_ntoa 函数前返回的字符串地址是有效的。若需要长期保存,则应该将字符串复制到其他内存空间。

View File

@@ -116,7 +116,7 @@ addrlen: 第二个结构体参数 servaddr 变量的字节长度
客户端调用 connect 函数后,发生以下函数之一才会返回(完成函数调用):
- 服务端接受连接请求
- 发生断网等一场状况而中断连接请求
- 发生断网等异常状况而中断连接请求
注意:**接受连接**不代表服务端调用 accept 函数,其实只是服务器端把连接请求信息记录到等待队列。因此 connect 函数返回后并不应该立即进行数据交换。
@@ -132,7 +132,7 @@ addrlen: 第二个结构体参数 servaddr 变量的字节长度
2. 结构体变量 serv_addr 中初始化IP和端口信息。初始化值为目标服务器端套接字的IP和端口信息。
3. 调用 connect 函数向服务端发起连接请求
4. 完成连接后,接收服务端传输的数据
5. 接收数据后调用 close 函数关闭套接字,结束与服务器端的连接。
5. 接收数据后调用 close 函数关闭套接字,结束与服务器端的连接。(对套接字调用close函数对应于向建立连接的对应套接字发送EOF。即如果客户端的套接字调用了close函数服务端read时候会返回0。)
#### 4.2.7 基于 TCP 的服务端/客户端函数调用关系

View File

@@ -22,7 +22,7 @@ write(sock, message, strlen(message));
str_len = read(sock, message, BUF_SIZE - 1);
```
二者都在村换调用 read 和 write 函数。实际上之前的回声客户端将 100% 接受字节传输的数据,只不过接数据时的单位有些问题。扩展客户端代码回顾范围,下面是,客户端的代码:
二者都在循环调用 read 和 write 函数。实际上之前的回声客户端将 100% 接受字节传输的数据,只不过接数据时的单位有些问题。扩展客户端代码回顾范围,下面是,客户端的代码:
```c
while (1)
@@ -52,7 +52,7 @@ while (1)
#### 5.1.3 如果问题不在于回声客户端:定义应用层协议
回声客户端可以提前知道接收数据的长度,这在大多数情况下是不可能的。那么此时无法预知接收数据长度时应该如何手法数据?这需要的是**应用层协议**的定义。在收发过程中定好规则(协议)以表示数据边界,或者提前告知需要发送的数据的大小。服务端/客户端实现过程中逐步定义的规则集合就是应用层协议。
回声客户端可以提前知道接收数据的长度,这在大多数情况下是不可能的。那么此时无法预知接收数据长度时应该如何收发数据?这需要的是**应用层协议**的定义。在收发过程中定好规则(协议)以表示数据边界,或者提前告知需要发送的数据的大小。服务端/客户端实现过程中逐步定义的规则集合就是应用层协议。
现在写一个小程序来体验应用层协议的定义过程。要求:
@@ -83,7 +83,7 @@ gcc My_op_server.c -o myserver
![](https://i.loli.net/2019/01/15/5c3d966b81c03.png)
其实主要是对程序的一点点小改动,只需要客户端固定好发送的格式,服务端按照固定格式解析,然后返回结果即可。
其实主要是对程序的一点点小改动,只需要客户端固定好发送的格式,服务端按照固定格式解析,然后返回结果即可。
书上的实现:
@@ -182,7 +182,7 @@ TCP 在实际通信中也会经过三次对话过程,因此,该过程又被
对于主机 A 首次传输的数据包的确认消息ACK 1001和为主机 B 传输数据做准备的同步消息SEQ 2000捆绑发送。因此此种类消息又称为 SYN+ACK。
收发数据前向数据包分配序号,并向对方通报此序号,这都是为了防止数据丢失做的准备。通过数据包分配序号并确认,可以在数据包丢失时马上查看并重传丢失的数据包。因此 TCP 可以保证可靠的数据传输。
收发数据前向数据包分配序号,并向对方通报此序号,这都是为了防止数据丢失做的准备。通过数据包分配序号并确认,可以在数据包丢失时马上查看并重传丢失的数据包。因此 TCP 可以保证可靠的数据传输。
通过这三个过程,这样主机 A 和主机 B 就确认了彼此已经准备就绪。
@@ -200,7 +200,7 @@ TCP 在实际通信中也会经过三次对话过程,因此,该过程又被
与三次握手协议相同,最后 + 1 是为了告知对方下次要传递的 SEQ 号。下面分析传输过程中数据包丢失的情况:
![](https://i.loli.net/2019/01/16/5c3ed371187a6.png)'
![](https://i.loli.net/2019/01/16/5c3ed371187a6.png)
上图表示了通过 SEQ 1301 数据包向主机 B 传递 100 字节数据。但中间发生了错误,主机 B 未收到,经过一段时间后,主机 A 仍然未收到对于 SEQ 1301 的 ACK 的确认因此试着重传该数据包。为了完成该数据包的重传TCP 套接字启动计时器以等待 ACK 应答。若相应计时器发生超时Time-out!)则重传。