• iron_man
    2019-09-07
    一直有个疑问,趁这堂课向老师请教一下,前面客户端发送消息时,消息长度转成网络序了,后面的消息为何没有转成网络序,如果消息里面含有数字呢?如果消息里面全是字符呢?

    作者回复: 非常好的问题。

    我们在网络传输中,一个常见的方法是把0-9这样的数字,直接用ASCII码作为字符发送出去,在这种情况下,你可以理解成发送出去的都是字符类型的数据,因为是字符类型的数据,就没有所谓的网络顺序了;而如果作为一个数据型数据,比如125,这时候可能就要作为一个4字节的整型数据进行传输,那么就会有字节序的问题了。

     1
     12
  • 徐凯
    2019-09-06
    第一个是不是跟windows文本换行与linux文本换行的字符不同有关 windows上好像是一个换行符一个回车符 linux是一个换行符
    
     3
  • JasonZhi
    2019-09-29
    老师,针对粘包问题会有相关的讲解吗?经常会听说相关的名词,但是还是不太懂具体是怎么样的。

    作者回复: 我理解所谓的粘包是数据报文的边界确定不清晰,造成报文解析的时候有overlap,数据解析不对。

    这个具体的解法讲义里也都有涉及到,通过合理设置报文边界,接收端缓冲报文并在解析时注意上下文,一般不会有大的问题。

     2
     2
  • 刘晓林
    2019-09-07
    老师,关于网络序和主机序,我有3个问题想要请教一下:
    1.在数据发送的时候,是先发送内存中高地址的数据,还是先发内存中低地址的数据?比如char* sendline="abcdef",是从a到f的顺序去发,还是从f到a的顺序去发。
    2.接受的时候,是现接受到的是网络序中的高地址,还是低地址?
    3.socket接口,如read,send这些函数,会自动帮我们完成主机序和网络序之间的转换吗,还是必须要自己去转?我看老师你有些数据显式调用了htonl(),有些没有,这是为什么呢?
    谢谢老师。

    作者回复: 1.如果是字符类型数据,肯定是从a到f这样的顺序拷贝到发送缓冲区发送的;
    2.网络中没有高地址或者低地址,网络中传输的是一个字节流,就像你例子里的abcdef....这样的顺序字节流;
    3.不会。对于数据型的数据如int需要调研htonl来转换,对于字符类型的数据,不需要转换。因为字符类型的数据,本质是ASCII编码,而int类型的数据则需要决定顺序。

     1
     2
  • wyf2317
    2019-09-08
    1. windos 和mac linux 的换行不一样。\r 或\r\n
    2. 所属的层级不一样,应用层和网络层
    但本质上就是人为预定的对二进制数据序列化的方式,没有太大的差别,都是通信协议。
    
     1
  • 卫江
    2019-09-06
    问题1,window与linux平台对于回车换行的编码不一致。
    问题2,协议本质来说就是大家协商好,便于沟通的内容形式。所以,tcp与我们自定义的协议本质来说没有什么不用,区别只是针对的业务不同而已!
    
     1
  • 张立华
    2019-09-06
    我的操作系统是:centos 7.4 64位操作系统。

    short int = 258;

    258=0x0102

    x的地址是(每次运行地址不一样): 0x7fffffffe33e

    258在内存中:

    低位                     高位                        
    0x7fffffffe33e            0x7fffffffe33f
    00000010                00000001

    也就是说,在我的linux电脑上,内存的数据,是小端字节序

    可以写个简单的程序,用gdb调试下,通过 x命令查看内存
    展开

    作者回复: 赞。

    
     1
  • 传说中的成大大
    2019-09-06
    message.message_length = htonl( n );
    message.message_type = 1;
    我在自己写代码实现的时候突然想起这两句代码为什么一个需要htonl一个不需要呢?

    作者回复: 我觉得是我错了,应该都需要的,因为我定义的MESSAGE_TYPE是一个int型值。好提醒,能pull一个PR过来么?要不我自己来吧。

     3
     1
  • Brave Shine
    2019-09-06
    1. linux和windows在编码http层面的不同?
    2. tcp的分组报文是传输层在协议栈层面怎么发tcp包的规范,这里指的是应用层报文
    
     1
  • xupeng1644
    2020-01-15
    老师 客户端发送message时 为什么不将messsage_type也转换成网络字节序 而只将message_length转换成网络字节序

    作者回复: 我认为你是对的,type类型确实也需要转为网络字节顺序。

    
    
  • zjstone
    2019-12-08
    
    read_line函数用很多次read操作,效率很低,老师应该发个高效率的版本:)

    作者回复: 你有什么更好的思路么?多次read调用在网络程序开发中很正常。

    
    
  • godtrue
    2019-11-23
    本文核心观点:
    1:TCP 数据是流式的——0/1的组合——符合规范的直流电——符合规范的交流电
    2:在发送端,当我们调用 send 函数完成数据“发送”以后,数据并没有被真正从网络上发送出去,只是从应用程序拷贝到了操作系统内核协议栈中,至于什么时候真正被发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。也就是说,我们不能假设每次 send 调用发送的数据,都会作为一个整体完整地被发送出去。
    3:接收端缓冲区保留了没有被取走的数据,随着应用程序不断从接收端缓冲区读出数据,接收端缓冲区就可以容纳更多新的数据。如果我们使用 recv 从接收端缓冲区读取数据,发送端缓冲区的数据是以字节流的方式存在的,无论发送端如何构造 TCP 分组,接收端最终受到的字节流总是有序的完整的,这些都有TCP严格保证。
    4:数据存储有大小端之别,只要统一就行,网络传输字节序使用大端
    5:都是0/1咋区分数据的边界,常用方式有两种,一是标明字节长度,二是使用特殊分隔符
    展开
    
    
  • 林林
    2019-11-04
    老师,关于大小端的问题,服务端和客户端互相发包的情况下,为了安全起见,是不是都应该统一进行大小端处理?比如发包都得先转成大端数据,收包再转成机器的顺序?(无论是字符数据还是数值数据)

    作者回复: 是的。实际上就是这样。

    
    
  • chs
    2019-10-31
    老师请问这个客户端协议的发送顺序是怎样的?是按照协议里字段的定义顺序发送即先发送数据长度然后发送数据类型最后是发送数据?

    作者回复: 这个对我们来说是透明的,不过你可以理解成先发送数据长度,再发送数据类型,最后是数据本身。

    
    
  • Steiner
    2019-10-20
    我想到一个问题,倘若发送端send一个很大的buf,而接收端如果只能接收定长的buf的话就不能一次性处理,这个时候是不是要像文中那样自定义一个结构体包含buf长度和buf来构成一个通信协议来达成一次性处理
    http又是怎么处理这种情况的,他是一次性还是分段呢

    作者回复: 好问题,这个在实际设计应用层协议的,是要着重考虑避免的,就是说边界的划分,应该是有限的,http的协议有head和body的区分,处理的好是可以分段处理的。比如先处理head,再处理body部分。

    
    
  • Edison.Chen
    2019-09-24
    老师,我在Linux平台下,照着你的程序写了一遍,客户端发数据,但是好像服务端不能够把数据包给解析出来。

    作者回复: 你写编译一下我这里的例子,看看是否能正确运行。

    你也可以把你的例子贴上来,大家一起分析。

     1
    
  • 甘远林
    2019-09-18
    大小端问题,如果两边机器的大小端一样,这样两边都不转也没问题吧

    作者回复: 关键是我们不知道对方机器的型号,是不是大小端一样的。

    
    
  • 有点意思
    2019-09-11
    老师好
    问题是这样的:
    客户端这边有两个线程:
    一个线程采集网卡流量存到环形缓冲区,另外一个线程从环形缓冲区读取并发送
    格式是:四字节长度+具体内容
    服务端收到后,根据提取到的长度去读取具体内容
    但是在程序运行了一段时间后,发现服务端处理报文出错了,原因是提取的长度是0,
    现在想到的是遇到这种特殊情况,直接断开连接在连,但是总感觉这样处理不好,有点应付差事一样
    我现在有个疑问 出现这种情况是不是一定是服务端拆包的逻辑或者客户端组包的逻辑出了问题 除此之外不会再有其他原因了
    使用原生socket在两台机子间发送接收大数据量的网卡流量 是不是一定能做到可靠没问题?
    展开

    作者回复: 是解析完的四字节长度为0,还是读到了0?如果提取的长度为0,说明写入的就是0啊,这个要看下发送端发的数据是否对的。

    
    
  • Steiner
    2019-09-11
    这个字节序转换是不是IP地址,端口,数据都要啊

    作者回复: 我其实觉得本地端口不需要,数据是需要的。就是双方通信的那个部分是需要的。

    
    
  • Steiner
    2019-09-11
    当我用htonl(999999999)时netstat -tanlp 显示的IP地址是0.0.0.0,数字小一点再试一次是127.0.0.1 当初地址绑定是就是127.0.0.01,这是怎么回事

    作者回复: 感觉是整型数越界了。

    
    
我们在线,来聊聊吧