Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should port number be converted to Network Byte Order when binding a socket?

Tags:

c

sockets

I came across this snippet of code which appeared in the guts of setting up a socket:

#define PORT xxxx

struct sockaddr_in self;
self.sin_family = PF_INET;
self.sin_port = htons(PORT);

I understand that we need to convert byte order of the data that we are transmitting over a network to Network Byte Order but I don't get why we need to convert port number to that as well when setting up a socket. I mean, when we do bind, isn't it a "local" thing? Say the port we intend to be bound is 1 and the machine actually uses little endian; now since we converted it into Network Byte Order, wouldn't we be binding a totally different port to the socket?

like image 312
Xufeng Avatar asked Mar 22 '14 05:03

Xufeng


People also ask

What is the purpose of byte ordering in network communication?

The network byte order is defined to always be big-endian, which may differ from the host byte order on a particular machine. Using network byte ordering for data exchanged between hosts allows hosts using different architectures to exchange address information without confusion because of byte ordering.

What is the Linux socket API used for maintaining the network byte order?

unsigned long htonl(unsigned long hostlong) − This function converts 32-bit (4-byte) quantities from host byte order to network byte order.

What function would you use to convert a long to a network byte order?

Your port will simply be a number stored in an integer, and as such it must be converted into the proper form. The htons() function does just that. It takes one parameter and returns it in the expected network-byte order.

What order is network order?

According to big endian byte ordering or network byte order the bits are transmitted in this order: bits 0-7 first, then bits 8-15, then 16-23 and bits 24-31 last.


2 Answers

I think let's assume you are using TCP. The port number is going to be in the packet header. That is going to be transmitted. So it will be in Network Byte Order.

like image 57
Hot.PxL Avatar answered Sep 29 '22 06:09

Hot.PxL


Are you asking why you the application programmer does it instead of the library doing it internally? If so, the only technical advantage I can think of is that it allows the application to do the conversion once and cache it and use it many times without requiring many conversions.

On TCP you only need to use it once per connection and typically won't make millions of connections. But on UDP you use it every time you send a packet, and it's reasonable to assume you'd make millions or billions of such calls.

Then, for myriad calls to say sendto() for UDP, or what have you, the re-ordered-if-necessary address is supplied to the OS which can copy it as-is directly into outgoing network packets.

The alternative of doing it in the kernel would require every call to sendto() to take what the app knows as the same address over and over, and reconvert it every time.

Since sendto() benefits from this, that was perhaps sufficient reason for them to have the rest of the API work the same way.

like image 39
Swiss Frank Avatar answered Sep 29 '22 06:09

Swiss Frank