strlen遇上小端模式

在写UDP客户端测试程序的时候,遇到了一个问题,然后百思不得其解,研究了一下午,豁然开朗。

首先看一下遇到的问题

     ConnProto conn;
        conn.type = 1;
        conn.srcuserid = 110;

        UserContent node;
        sprintf(node.strName,"%s","aaaaaa");
        sprintf(node.strPassword,"%s","123456");

        char buf[1024];
        memset(buf,0,sizeof(buf));
        
        char *pData = buf;
        ConnProto *pConn = (ConnProto*)pData;
        *pConn = conn;

        pData += sizeof(ConnProto);
        UserContent *pNode = (UserContent*)pData;
        *pNode = node;
sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&servaddr,len);

可是接收端显示只接受到1个字节大小,怎么可能啊。我明明发了两个结构体大小啊(38字节)。

struct ChatContent
{
    int destuserid;
    char strContent[200];
};
struct UserContent
{
    char strName[20];
    char strPassword[10];
};

将sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&servaddr,len);改成

sendto(sockfd,buf,sizeof(ConnProto)+sizeof(UserContent),0,(struct sockaddr*)&servaddr,len);

就可以了,接收端提示收到38个字节。

 

思考:为甚呢??/

我们知道strlen函数遇到 '\0' 就不向后了。那么这个  strlen(buf)是怎么等于1的呢??

原来,在内存中,先是存储  conn.type = 1;

在内存中就是  

 高地址 -------------->低地址

0000 0000 0000 0001  (4字节)

0对应的ASCII码就是空字符 '\0'

根据strlen(buf)=1  ,我们猜想  是不是跟大小端有关系呢??(当然当时我是没有这么机智的,还是憋了好久才想到。这里为了简化我木讷的脑袋思考过程)

于是,将  conn.type = 1;改为conn.type = 0;

显示 strlen(buf)=0.

哎呀,变了,那么说明改到了对的地方。接着将onn.type = 0x0x7fffffff;

显示 strlen(buf) = 5。

怎么是5了,不是应该是4吗??别忘了后面还有conn.srcuserid = 110;  

这更加证实了 这跟大小端存储有关。

记不得Linux是大端还是小端存储了,没关系,我们测试一下。

#include <stdio.h>
#include <stdlib.h>

int main()
{
        union
        {
                short a;
                char c;
        }u;

        u.a = 0x1234;
        printf("%d\n",u.c);
}

输出:

52

哦,是小端。证实了猜想。

 

接着为了方便,conn.type = 65;   65对应ASCII码的  A

printf("%d\n",strlen(buf));
printf("%s\n",buf);

输出;

1

A

哦哦,原来在内存中,大家都是以二进制存储的,管你是什么类型,char还是ConnPoto结构体。在以%s的格式打印出就是 A .信不信还能让他输出65.

printf("%d\n",strlen(buf));
printf("%d\n",*buf);

输出;

1

65

看吧。

今天又学到一点。记住一切东西在内存中都是 二进制01存储的,因为我们的输出格式不同才导致结果不同。以后不要畏惧不同格式了。

posted @ 2017-06-06 18:04  ren_zhg1992  阅读(206)  评论(0)    收藏  举报