• 从网络字节流中提出整数


    最近在做一个项目,就是设计一套通信协议,利用nginx来实现解析。协议内容是包括整数和字符串,现在客户端收到服务器端发送的网络字节流时,需要从中提取出整数,再根据整数决定发送数据量的大小。如下所示:

    p = u->buffer.pos;

    num=*(int*)p

    p指向接收到的网络字节流,用这么方式解析得到的整形num不是服务器端发送的数字,是一个很大的数。不对,于是换了种方式:

    memcpy(num,p,sizeof(int));
    printf("num is %d ",*(int*)num);

    结果还是一样。

    但是输出字节流p,能看到后面的字符串是能得到的,但是前面的整数得不到

    for(i=0;i<9;i++){
      printf("i :%c ",p[i]);
    }

    于是改成以16进制形式输出,结果是可以查看到整数值:

    pos last 0
    pos last 0
    pos last 0
    pos last 5
    pos last 77
    pos last 67
    pos last 70
    pos last 31
    pos last 66

    即第4字节的那个5正式服务器端发送的数字,这说明网络字节流是对的。只是不能那样取出来。

    这个时候就必须熟悉网络字节流的概念了,搜了下:

    网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
    主机字节序就是我们平常说的大端和小端模式:不同的 CPU 有不同的字节序类型,这些字节序是指整数在内存中保存的顺序 这个叫做主机序。

    就是网络字节流的序列和主机的序列可能不一样,所以需要一些函数进行转换,linux提供了四个函数:


    为了进行转换 bsd socket提供了转换的函数 有下面四个
    htons 把unsigned short类型从主机序转换到网络序
    htonl 把unsigned long类型从主机序转换到网络序
    ntohs 把unsigned short类型从网络序转换到主机序
    ntohl 把unsigned long类型从网络序转换到主机序

    把代码改成:

    p=u->buffer.pos;
    htnum=ntohl(*(int*)p);
    printf("htmum=%d,%x ",htnum,htnum);

    搞定得到正确结果。

    这说明进行网络编程时得注意网络字节流的序列,否则不能提取出对应的数据。

  • 相关阅读:
    js 复制 浏览器 点击 copy
    php 百度地图 腾讯地图 转换坐标
    Excel PHP html select option 替换
    python教程
    Eclipse 总是在编译的时候卡住
    python+Eclipse+pydev环境搭建1
    python+Eclipse+pydev环境搭建
    Pycharm
    如何卸载eclipse中的pydev
    Eclipse的PyDev插件安装及解决安装后找不到的问题
  • 原文地址:https://www.cnblogs.com/hahawgp/p/3709625.html
Copyright © 2020-2023  润新知