简体   繁体   English

在两个套接字之间传输整数值C ++

[英]Transmitting integer values between two sockets c++

I have a c++ socket program where there are two processes. 我有一个c ++套接字程序,其中有两个进程。 The server process and client process. 服务器进程和客户端进程。 The client registers with the server and listens on a port for any message from server. 客户端向服务器注册,并在端口上侦听来自服务器的任何消息。

I have defined a "char *buffer" which will have my message. 我定义了一个“ char * buffer”,它将包含我的消息。 The message size is say 59000 Bytes. 消息大小为59000字节。 Now before transmitting the message i am adding the message size at the beginning of the buffer, 现在,在传输消息之前,我要在缓冲区的开头添加消息大小,

size=htonl(59000)
Buffer= size + <Actual Message>

so that client process when ever it gets a message it reads first two bytes to get size first, knows the size of message transmitted and then it reads the complete message from the socket. 这样,客户端进程在收到消息时会先读取两个字节以获取大小,然后知道所传输消息的大小,然后再从套接字读取完整的消息。 This is done as below 如下完成

59000 in binary format is          00000000 00000000 11100110 01111000  
htonl(59000) in binary format is   01111000 11100110 00000000 00000000

I used memcpy to copy this size to charcter buffer. 我使用memcpy将这个大小复制到charcter缓冲区。

memcpy(buffer, &size, 4) <since size of int is 4>

After transmitting the message at client when i read the first two bytes i get the size as zero. 在客户端发送消息后,当我读取前两个字节时,我得到的大小为零。 But if i read the next two bytes i get the correct size that is 59000. The way i am reading the message size at client is as mentioned below 但是,如果我读取接下来的两个字节,则会得到正确的大小,即59000。我在客户端读取消息大小的方式如下所述

int messageSize=0;
memcpy(&messageSize, buffer, 2 );

Can some one please explain me why the message size is stored in the second two bytes and not in the first two bytes. 有人可以解释一下为什么消息大小存储在后两个字节中而不是在前两个字节中吗?

I would be very grateful to you if you can help me. 如果您能帮助我,我将不胜感激。 I have been trying to understand this from quite some time. 我已经尝试了很长时间了。

There is one serious mistake in your explanation : 您的解释中有一个严重错误:

59000 in binary format is          00000000 00000000 11100110 01111000  
htonl(59000) in binary format is   01111000 11100110 00000000 00000000

is wrong it really is the ohter way around so 是错的,这真的是另一种方式

59000 in binary format is          01111000 11100110 00000000 00000000
htonl(59000) in binary format is   00000000 00000000 11100110 01111000  

that is this is the case on cpu that is little endian. 在cpu上是little endian的情况就是这样。 So since a int is 4 bytes, this perfectly explains why you receive 2 zero bytes first. 因此,由于int为4字节,因此这可以完美解释为什么您首先收到2个零字节。

htonl stands for host to network long. htonl表示网络主机。 host order is the ordering of the bytes on the host. 主机顺序是主机上字节的顺序。 This can be different on little and big endian machines, but network order is well defined and it must be because otherwise computers could not talk to eachother. 在大小端的机器上,这可能会有所不同,但是网络顺序已明确定义,这一定是因为否则计算机将无法相互通信。

There is also htons: for short and the reverse of htons and htonl is ntohl and ntohs 也有htons:简而言之,htons和htonl的相反含义是ntohl和ntohs

These functions do the exact same thing as their counterparts, that is in a big endian system they don't do anything at all, in little endian they reverse the byte order of whatever comes in. htons(htons(x)) does nothing. 这些函数执行与它们对应的函数完全相同的操作,即在大字节序系统中,它们根本不执行任何操作,在小字节序系统中,它们反转输入的字节顺序。htons(htons(x))不执行任何操作。 There is no way to detect for the computer if a value is byte reversed. 无法检测到计算机是否将值反转为字节。 use ntohl and ntohs when coming from network order to host order, you'll need this at the client when you receive the first 4 bytes and want to know the length. 从网络订单到主机订单时使用ntohl和ntohs,当您收到前4个字节并想知道长度时,将在客户端上使用它。

htonl converts a long (meaning 4-byte int) from host-byte-order to network-byte-order. htonl将一个长整数(表示4字节整数)从主机字节顺序转换为网络字节顺序。 Network-byte-order is defined as big-endian, that is the most significant byte of a multi-byte number is first. 网络字节顺序定义为big-endian,即多字节数字中的最高有效字节在前。 The host-byte-order is either big-endian (in which case htonl does nothing) or little-endian (in which case htonl reverses the bytes). 主机字节顺序为big-endian(在这种情况下htonl不执行任何操作)或little-endian(在这种情况下htonl反转字节)。

In all cases, the bytes representing 59000 will be transmitted as 0x00 0x00 0xe6 0x78 . 在所有情况下,代表59000的字节将作为0x00 0x00 0xe6 0x78 So if you only read the first two bytes, you will always get 0x00 0x00 . 因此,如果仅读取前两个字节,则将始终获得0x00 0x00 To read the value correctly on all systems, you need to read all four bytes into a 32-bit integer, and then call ntohl to convert the number from network-byte-order to host-byte-order. 要在所有系统上正确读取该值,需要将所有四个字节读取为32位整数,然后调用ntohl将数字从网络字节顺序转换为主机字节顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM