【问题标题】:Character becoming int when sent over socket通过套接字发送时字符变为 int
【发布时间】:2013-12-08 09:17:45
【问题描述】:

好的,我通过套接字发送原始数据。

unsigned char data [] = {0xFA, 0xDE, 0xDB, 0xAD, 0x00, 0x00, 0x00, 0x06, 0x54, 0x65, 0x61, 0x67,0x61, 0x6E, 0x19, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x68, 0x6F, 0x77, 0x20, 0x61, 0x72, 0x65, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x66, 0x62, 0x67, 0x67, 0x6F, 0x74, 0x3F };

最终与此相同。

但是当它被接收时它会像这样结束

fffffffa ffffffde ffffffdb ffffffad 0 0 0 6 54 65 61 67 61 6e 19 48 65 6c 6c 6f 20 68 6f 77 20 61 72 65 20 79 6f 75 20 66 62 67 67 6f 74 3f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

注意原来的前 4 个字节是如何变成 16 个字节的。

知道是什么原因造成的吗?

一点代码

char data[512];
if ( socket.Receive(address, data, sizeof(data)) ){
    char *point = data;
    if ( (unsigned int ) *point == 0xFADEDBAD )
            fprintf(stderr, " WIN \n");

//////////////////// 上面的接收函数 /////////////////

            int Receive( Address & sender, void * data, int size )
            {
                    assert( data );
                    assert( size > 0 );

                    if ( socket == 0 )
                            return false;


                    #if PLATFORM == PLATFORM_WINDOWS
                    typedef int socklen_t;
                    #endif

                    sockaddr_in from;
                    socklen_t fromLength = sizeof( from );

                    int received_bytes = recvfrom( socket, (char*)data, size, 0, (sockaddr*)&from, &fromLength );

                    if ( received_bytes <= 0 )
                            return 0;

                    unsigned int address = ntohl( from.sin_addr.s_addr );
                    unsigned int port = ntohs( from.sin_port );

                    sender = Address( address, port );

                    return received_bytes;
            }

    private:

            int socket;
    };

}

//////// 数据是如何发送的 /////////////////////////////////////////

unsigned char data [] = {0xFA, 0xDE, 0xDB, 0xAD, 0x00, 0x00, 0x00, 0x06, 0x54, 0x65, 0x61, 0x67,0x61, 0x6E, 0x19, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x68, 0x6F, 0x77, 0x20, 0x61, 0x72, 0x65, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x66, 0x61, 0x67, 0x67, 0x6F, 0x74, 0x3F };

socket.Send (address, (char*)data, sizeof (data)  );

////////////// 方法//////////////

 bool Send( const Address & destination, const void * data, int size )
            {
                    assert( data );
                    assert( size > 0 );

                    if ( socket == 0 )
                            return false;

                    sockaddr_in address;
                    address.sin_family = AF_INET;
                    address.sin_addr.s_addr = htonl( destination.GetAddress() );
                    address.sin_port = htons( (unsigned short) destination.GetPort() );

                    int sent_bytes = sendto( socket, (const char*)data, size, 0, (sockaddr*)&address, sizeof(sockaddr_in) );

                    return sent_bytes == size;
            }

【问题讨论】:

  • 你是怎么写字节的?你可以发布代码的sn-p吗?
  • 只是猜测:第五个字符为空。可能会终止您的阵列...

标签: c++ sockets character-encoding


【解决方案1】:

将字符转换为 int 的不是套接字,而是您将它们接收到有符号(!您不是在声明数据无符号!)字符。您没有显示输出“坏”十六进制值的部分,但我认为它类似于

printf("%02x", data[i])

它采用 data[i] 中的(有符号!)字符,将其转换为 4 字节整数(其值可能在 -128 和 127 之间,十六进制的 0xffffff80 到 0x0000007f 之间),然后输出该整数。

在接收端声明“unsigned char data[512]”可以解决这个问题。

还有,你的

if ( (unsigned int ) *point == 0xFADEDBAD )

错了,应该改成

if ( *(unsigned int *) point == 0xFADEDBAD )

你不会用 *point 来访问一个(1 字节)字符,然后将此字符转换为 int;您想将指针转换为指向 4 字节整数的指针,然后通过指针访问这 4 字节。

但是,根据您的硬件,您可能仍会遇到字节顺序和对齐问题。如果您不了解这些条款,请在 Google 上搜索。

【讨论】:

  • 非常感谢。错过了签名的字符,那是我智障了 XD,我们都有自己的时刻。
  • 假设 little endian 比较不成立,因为这样的类型双关语会给你0xaddbdefa
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 2014-09-02
  • 2023-03-19
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
  • 2011-03-30
相关资源
最近更新 更多