开发者

socket conversation terminator

While reading data in socket its important either keep a message terminator symbol or add the Packet size information at the begening of the message.

If a terminator symbol is used and a binary message is sent there is no guarantee that the terminator symbol would not appear in the middle of the message (unless some special encoding is used).

On the other hand if size information is attached. size information is unsigned and if one byte is used for it it cannot be used to transfer messages longer than 256 bytes. if 4 byte integer is used. its not even guaranteed that 4 bytes will come a s whole. just 2 bytes of the size information may come can assuming the size information has arrived it may use that 2 bytes and rest of the integer data will be discarded. waiting for 4 bytes to be available on read buffer may cause infinite awaiting if only 3 bytes are available on the buffer (e.g. i开发者_高级运维f total buffer is 7 bytes or 4077 bytes long).

here comes two possible ways

  1. sizeInfo separator chunk

    read until the separator is found once found read until sizeInfo bytes passed

  2. keep an unreadyBytes initialized at 4 upon receiving the sizeInfo change it accordingly

which one of these two is safer to use ? Please Criticize

Edit

My central question is how to make sure that the size bytes has arrived properly. assuming messages are of variable size.


its not even guaranteed that 4 bytes will come a s whole. just 2 bytes of the size information may come can assuming the size information has arrived it may use that 2 bytes and rest of the integer data will be discarded. waiting for 4 bytes to be available on read buffer may cause infinite awaiting if only 3 bytes are available on the buffer (e.g. if total buffer is 7 bytes or 4077 bytes long).

If you have a 4 bytes length descriptor you should always read at least 4 bytes, because the sender should have written this bytes in every message your server is receiving. If you can't get them, maybe there has been a problem in transmission. I really can't understand your problem.

Anyway I'll suggest to you not to use any separator chunk. Put an header at data blocks you are transmitting and use a buffer to reconstruct the packet flow.

You must at least read the header of a packet to determine its length.

You can define a basic structure for a packet:

struct packet{
     uint32 id;
     char payload[MAX_PAYLOAD_SIZE];
};

The you read data from socket storing them into a buffer:

struct packet buffer;

Then you can read the data from the socket: int n; n = read(newsocket, &buffer, sizeof(uint32) + MAX_PAYLOAD_SIZE);

read returns the number of bytes read. If you read exactly a packet from the sender, then n = id. Otherwise maybe you read more data (es. the sender sent to you more packets). If you are receiving a stream of data split into unit (represented by packet structures), then you may use an array of packet to store the complete packet received and a temporarily buffer to manage incoming fragments. Something like:

struct packet buffer[MAX_PACKET_STORED]; char temp_buffer[MAX_PAYLOAD_SIZE + 4];

int n; n = read(newsocket, &buffer, sizeof(uint32) + MAX_PAYLOAD_SIZE);

//here suppose have received a packet of 100 Byte payload + 32 bit of length + 100 Byte //fragments of the next packet. //then:

int first_pack_len, second_pack_len;

first_pack_len = *((uint32 *)&temp_buffer[0]); //retrieve packet length

memcpy(&packet_buffer[0], temp_buffer, first_pack_len + sizeof(uint32)) //store the first packet into the array

second_pack_data_available_in_buffer = n - (first_pack_len + sizeof(uint32)); //total bytes read minus length of the first packet read
second_pack_len = *((int *)&temp_buffer[first_pack_len + sizeof(uint32)]);

I hope to have been clear enough. But maybe I'm misunderstanding your question. Pay attention also that if the 2 end-systems communicating could have different endiannes, so it's a better idea use htonl/ntohl function on length when sending/receving length value. But this is another issue)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜