时长:大小9.44M
作者回复: 都是强人😄
作者回复: 总结的很牛
作者回复: 👍
作者回复: TCP是流协议,根本不存在所谓粘包一说。应用层协议在设计的时候,是需要充分考虑到数据解析和还原的问题,如果设计不好,导致数据无法还原,那是应用层协议设计不佳,并不是说TCP天然有粘包问题。
作者回复: DMA区域都知道,🐂。
作者回复: 在非阻塞I/O的情况下,send函数是"能写多少写多少",所以n_written就不等于remaining了,而send函数为了同时对阻塞I/O和非阻塞I/O起作用,就用while循环了。
作者回复: 表示缓冲区就那么大,装不下你要的那么大的字节流,就返回了目前能装下的部分,剩下的部分应用程序要自己接着往里装。
作者回复: 👍
作者回复: 正在进行中
作者回复: 1.是减少一个0.
2.我想表达的意思是TCP协议给我们提供了一个透明的交互方式,数据的接收是实现的细节,我们并不需要知道这个细节。如果你从要感知这个细节角度出发,确实是不透明的。
作者回复: 因为数据像流水一样,不会结束,所以叫做stream流。
作者回复: 就是说读的时候可能读不到你指定大小的字节流;而发送的时候如果是阻塞套接字,则会全部发送完;只有当非阻塞套接字的时候,才可能发送的字节数和请求的字节数不一致。该系列的后面几讲会讨论到这方面的内容。
作者回复: 首先,TCP的报文会被封装成一个一个TCP包,每个包都有一个sequence序列号,每个包里包含了一定的字节,当这个包被接收端接收(放到接收缓冲区中),接收端发送一个ACK,这个ACK和sequence对应,这样服务端就可以知道哪些包被接收,哪些包没有被接收。
按照你的例子,我们以400为包大小,发送了三个ACK,就可以认为1200字节发送结束。
服务端是不需要知道数据是否发送完毕的,因为TCP是一个流式的,没有办法知道客户端下个时刻还会不会发送数据,服务端只要告诉客户端我收到了1200字节就可以了。
作者回复: 我理解不是这样的,咱们调用write就是一个系统调用,就会有用户态-内核态的上下文切换,你说的这个问题,确实是实战中应该尽量避免的,我在后面的提高篇中会针对你说的这个情况讲到一些技巧。
作者回复: 答疑篇会稍微点拨一下C语言
作者回复: 如果你问的是第二个实验的结果,其实是这样的,确实每次发送都会打印出"send into buffer"这句话,问题是这里的程序一次性的将query字符串发送到了发送缓冲区,而发生缓冲区如果足够大,那么是可以一次性的容纳这部分数据的,所以当我们把发送字节数从从 10240000 调整为 1024000,就会直接看到"send into buffer"这句话
作者回复: 1.bzero对地址进行了置0处理,相当于初始化。否则地址就是错的;
2.cliaddr在accept函数中是传了一个地址的,这相当于是accept函数的输出参数,这样就可以知道连接上来的客户端的信息,比如IP。
作者回复: 阻塞那部分确实是这样的,当然,可以为read设置超时。