Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do recv() and send() convert the messages in network order format automatically?

Tags:

c

sockets

recv

I am very new in socket programming. I found that before sending messages we have to convert host byte order into network byte order. I have taken a look on many examples given on various sites but nobody have changed there messages into network byte order before sending the message. They have used this byte order changing only in case of setting values in variable of struct sockaddr_in (in case of port number and in case of ip address).

Ex:-

sock_addr.sin_port=htons(12000) 

or

sock_addr.sin_addr.s_addr=htonl(INADDR_ANY) 

etc.

Why don't they use this hton or ntoh in case of send() or recv() for sending or receiving messages? Do these functions automatically perform byte order conversion?

This question may be very silly. But please help me I am totally confused.

like image 597
Nishant Avatar asked Apr 16 '14 10:04

Nishant


2 Answers

There are a few reasons, most of which are variations of "they're being lazy."

  • First, you probably don't need to touch the port number and associated integers. They're integers. They're treated as integers by the processor and only the host uses the number, so it's always correct. In fact, if two machines with different byte-orderings open port 12000 the way you cite, they can't connect, because htons(12000) is going to be 12000 on one machine (0x2EE0) and 57390 on the other (0xE02E).

  • Generally, examples pass ASCII strings from client to server (or vice versa) with send() and recv(), which don't need conversion to/from network byte ordering, because each character fits in a single byte; remember that those macros change the byte ordering, so a byte is a byte. If you send anything bigger, though, you absolutely should "externalize" your data.

  • Lastly, if you can guarantee that everybody is running on a processor with the same architecture, you technically don't need network-ordering, because both processors will read the byte order the same. Please don't rely on this, but if you test without the conversion and everything works out fine, that's why.

The correct behavior is that, if you're sending an integer outside of your program, you should use htons() or htonl() on it, first. If you're receiving an integer, you should use ntohs() or ntohl(). Anything inside your program or taking up a single byte, you leave alone.

Anything else, you leave alone, provided the languages use the same encoding (i.e., a C-like, NULL-terminated string or an IEEE 754 floating-point number). If not, you need to write code to externalize the data or use a library like in RPC or CORBA.

like image 88
John C Avatar answered Sep 17 '22 15:09

John C


Do these functions automatically perform byte order conversion?

No. They can't. It is impossible to know in an arbitrary byte stream where an integer that needs conversion to network byte order is.

like image 32
user207421 Avatar answered Sep 21 '22 15:09

user207421