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

3

8

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.

Awe answered 16/4, 2014 at 10:33 Comment(2)
Not silly, indeed, it is very relevant question (-:Request
Extremely useful for beginnersChronic
W
4

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.

Wavelet answered 16/4, 2014 at 11:7 Comment(3)
You most certainly do have to convert the port number to network byte order. This is one instance where the designers of the Sockets API were lazy.Clinandrium
Strange to see that such useful answer got no upvotes.Request
Is the description "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)." correct? Would not either machine will open port 12000 despite the endian of the machine? The socket type SOCK_STREAM is designed to handle port number in network byte order correctly.Railroad
C
1

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.

Clinandrium answered 16/4, 2014 at 22:57 Comment(0)
K
0

First of all, If you are very new in socket programming I'd recomend you this guide http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html is a really nice guide to learn how to use sockets properly.

After this, I guess that you are missing something in the sending/receiving process using sockets.

The process is create socket->bind the socket->connect -> send/receive

You use the hton/nths before the binding and when you use UDP Sockets but not during the send/recv function because you are already connected.

Kissee answered 16/4, 2014 at 10:46 Comment(2)
does it mean, if I use htons before binding the socket and when I send messages by send() function then my message will be in network byte order...... and it doesn't require any use of htons ?Awe
htons means HostTONetworkShort and htonl means HostToNetworkLong, so they are only used to convert integers, your message will be a string of characters and characters have one byte size, because of that these characters don't need to be converted, there can not be any mistake with the network order with one single byteKissee

© 2022 - 2024 — McMap. All rights reserved.