getting data out of the recv( ) buffer

I'm experimenting with writing TCP sockets in C++ and I'm stuck on a certain step. I've connect()ed, listen()ed, and accept()ed a connection from a client. My test client has send() a simple 6-byte stream, made up of three uint16_t integers. I call recv() on the server end and can verify that 6 bytes are being received. Now I'm trying to figure out how to get the data out of the receiving buffer. I'm using the command:

(bytes_recv = recv(sockfd, recv_buf, sizeof(recv_buf), 0))

recv_buf is defined as:
char recv_buf[6];

Can you tell me how I would "extract" three uint16_t's out of the char array and into a struct? (The struct consisting of three uint16_t memebers)? Thanks.

jp
[760 byte] By [scjp] at [2007-11-19 19:33:51]
# 1 Re: getting data out of the recv( ) buffer
(bytes_recv = recv(sockfd, recv_buf, sizeof(recv_buf), 0))

This may recieve less than 6 bytes.
recv will return whenever it recieves any data from the client (with a minimum value that may be changed as a socket property), or when the buffer is full.
If you need to recieve these 6 bytes, you must use the MSG_WAITALL flag as fourth argument of recv:

(bytes_recv = recv(sockfd, recv_buf, sizeof(recv_buf), MSG_WAITALL))

Now, it returns when the 6 bytes are recieved, or if the connection has been closed.

Can you tell me how I would "extract" three uint16_t's out of the char array and into a struct? (The struct consisting of three uint16_t memebers)? Thanks.

Declare recv_buf as an array of uint16_t:

uint16_t recv_buf[3];

size_t i;

(bytes_recv = recv(sockfd, recv_buf, sizeof(recv_buf), MSG_WAITALL))

for(i=0;i<3;++i) recv_buf[i]=ntohs(recv_buf[i]);

Note that you must call ntohs in the server application to convert the data from the network byte order to the machine byte order.
Similarly, you must call htons on each value in the client application, to convert data from machine byte order to network byte order.
This work is necessary if the two machines may have different CPU architectures (for example PowerPC and x86).

A second method, more portable (which may work as well as it is possible, with 9 bits machines), assuming that the 9th bit is ignored for communication, would be that:
On the client side : spread uint16_t into two bytes whose values are in range [0,255].

void uint16_to_bytes(uint16_t value, unsigned char p[2])
{
p[0]=value & 0xFF;
p[1]=(value>>8) & 0xFF;
}

On the server side : pack these two bytes back into a unit16_t value, or an integer type containing at least 16 bits.

The first (simplier) solution is probably the way to go.

Under Win32, you may need an explicit cast from uint16_t* to char*:

(bytes_recv = recv(sockfd, (char*)recv_buf, sizeof(recv_buf), MSG_WAITALL))

Under UNIX systems, you should'nt need it, since the required type is void*.
SuperKoko at 2007-11-9 13:52:31 >
# 2 Re: getting data out of the recv( ) buffer
[ Redirected thread ]
Andreas Masur at 2007-11-9 13:53:32 >