· 6 years ago · Feb 19, 2020, 01:28 PM
1Guide de Beej sur la programmation réseau
2Utilisation de sockets Internet
3
4Salle Brian «Beej Jorgensen»
5
6v3.1.2, Copyright © 13 novembre 2019
7
8Intro
9Public
10Plateforme et compilateur
11Page d'accueil officielle et livres à vendre
12Remarque pour les programmeurs Solaris / SunOS
13Remarque pour les programmeurs Windows
14Politique de messagerie
15Miroir
16Remarque pour les traducteurs
17Copyright, distribution et mentions légales
18Dévouement
19Publication d'informations
20Qu'est-ce qu'une prise?
21Deux types de prises Internet
22Non-sens de bas niveau et théorie des réseaux
23Adresses IP, structs et liaison de données
24Adresses IP, versions 4 et 6
25Sous-réseaux
26Numéros de port
27Ordre des octets
28structs
29Adresses IP, deuxième partie
30Réseaux privés (ou déconnectés)
31Passer d'IPv4 à IPv6
32Appels système ou interruption
33getaddrinfo()—Préparez-vous au lancement!
34socket()—Obtenez le descripteur de fichier!
35bind()- Sur quel port suis-je?
36connect()-Hé toi!
37listen()- Quelqu'un va-t-il m'appeler?
38accept()- "Merci d'avoir appelé le port 3490."
39send()et - recv()Parle-moi, bébé!
40sendto()et - recvfrom()Parlez-moi, à la manière de DGRAM
41close()et - shutdown()Sortez de mon visage!
42getpeername()-Qui êtes vous?
43gethostname()-Qui suis je?
44Contexte client-serveur
45Un serveur de flux simple
46Un client de flux simple
47Prises de datagramme
48Techniques légèrement avancées
49Blocage
50poll()- Multiplexage d'E / S synchrone
51select()- Multiplexage d'E / S synchrone, Old School
52Gestion des send()s partiels
53Sérialisation - Comment empaqueter des données
54Fils de l'encapsulation des données
55Paquets de diffusion - Bonjour tout le monde!
56Questions courantes
57Pages de manuel
58accept()
59Synopsis
60La description
61Valeur de retour
62Exemple
63Voir également
64bind()
65Synopsis
66La description
67Valeur de retour
68Exemple
69Voir également
70connect()
71Synopsis
72La description
73Valeur de retour
74Exemple
75Voir également
76close()
77Synopsis
78La description
79Valeur de retour
80Exemple
81Voir également
82getaddrinfo(), freeaddrinfo(),gai_strerror()
83Synopsis
84La description
85Valeur de retour
86Exemple
87Voir également
88gethostname()
89Synopsis
90La description
91Valeur de retour
92Exemple
93Voir également
94gethostbyname(), gethostbyaddr()
95Synopsis
96La description
97Valeur de retour
98Exemple
99Voir également
100getnameinfo()
101Synopsis
102La description
103Valeur de retour
104Exemple
105Voir également
106getpeername()
107Synopsis
108La description
109Valeur de retour
110Exemple
111Voir également
112errno
113Synopsis
114La description
115Valeur de retour
116Exemple
117Voir également
118fcntl()
119Synopsis
120La description
121Valeur de retour
122Exemple
123Voir également
124htons(), htonl(), ntohs(),ntohl()
125Synopsis
126La description
127Valeur de retour
128Exemple
129inet_ntoa(), inet_aton(),inet_addr
130Synopsis
131La description
132Valeur de retour
133Exemple
134Voir également
135inet_ntop(), inet_pton()
136Synopsis
137La description
138Valeur de retour
139Exemple
140Voir également
141listen()
142Synopsis
143La description
144Valeur de retour
145Exemple
146Voir également
147perror(), strerror()
148Synopsis
149La description
150Valeur de retour
151Exemple
152Voir également
153poll()
154Synopsis
155La description
156Valeur de retour
157Exemple
158Voir également
159recv(), recvfrom()
160Synopsis
161La description
162Valeur de retour
163Exemple
164Voir également
165select()
166Synopsis
167La description
168Valeur de retour
169Exemple
170Voir également
171setsockopt(), getsockopt()
172Synopsis
173La description
174Valeur de retour
175Exemple
176Voir également
177send(), sendto()
178Synopsis
179La description
180Valeur de retour
181Exemple
182Voir également
183shutdown()
184Synopsis
185La description
186Valeur de retour
187Exemple
188Voir également
189socket()
190Synopsis
191La description
192Valeur de retour
193Exemple
194Voir également
195struct sockaddr et copains
196Synopsis
197La description
198Exemple
199Voir également
200Plus de références
201Livres
202Références Web
203RFC
204Intro
205Hey! La programmation de socket vous a déprimé? Est-ce que c'est un peu trop difficile à comprendre à partir des manpages? Vous voulez faire de la programmation Internet cool, mais vous n'avez pas le temps de parcourir un tas de structs en essayant de comprendre si vous devez appeler bind()avant vous connect(), etc., etc.
206
207Bien devinez quoi! J'ai déjà fait ce sale boulot et je meurs d'envie de partager l'information avec tout le monde! Vous êtes arrivé au bon endroit. Ce document devrait donner au programmeur C compétent moyen le bord dont il a besoin pour maîtriser ce bruit de réseau.
208
209Et vérifiez-le: j'ai finalement rattrapé l'avenir (juste à temps, aussi!) Et j'ai mis à jour le Guide pour IPv6! Prendre plaisir!
210
211Public
212Ce document a été écrit comme un tutoriel, pas une référence complète. Il est probablement à son meilleur lorsqu'il est lu par des personnes qui commencent tout juste avec la programmation de socket et qui cherchent un pied à terre. Ce n'est certainement pas le guide complet et complet de la programmation des sockets, en aucun cas.
213
214Avec un peu de chance, cependant, il suffira juste que ces pages de manuel commencent à donner un sens… :-)
215
216Plateforme et compilateur
217Le code contenu dans ce document a été compilé sur un PC Linux en utilisant le gcccompilateur de Gnu . Il devrait cependant s'appuyer sur à peu près n'importe quelle plate-forme qui l'utilise gcc. Naturellement, cela ne s'applique pas si vous programmez pour Windows - voir la section sur la programmation Windows ci-dessous.
218
219Page d'accueil officielle et livres à vendre
220Cet emplacement officiel de ce document est:
221
222https://beej.us/guide/bgnet/
223Vous y trouverez également des exemples de code et des traductions du guide dans différentes langues.
224
225Pour acheter des exemplaires imprimés bien reliés (certains les appellent des «livres»), visitez:
226
227https://beej.us/guide/url/bgbuy
228J'apprécierai l'achat car il aide à maintenir mon style de vie de rédaction de documents!
229
230Remarque pour les programmeurs Solaris / SunOS
231Lors de la compilation pour Solaris ou SunOS, vous devez spécifier des commutateurs de ligne de commande supplémentaires pour la liaison dans les bibliothèques appropriées. Pour ce faire, ajoutez simplement « -lnsl -lsocket -lresolv» à la fin de la commande de compilation, comme ceci:
232
233 $ cc -o server server.c -lnsl -lsocket -lresolv
234Si vous obtenez toujours des erreurs, vous pouvez essayer d'ajouter davantage un -lxnetà la fin de cette ligne de commande. Je ne sais pas exactement ce que cela fait, mais certaines personnes semblent en avoir besoin.
235
236Un autre endroit où vous pourriez rencontrer des problèmes est l'appel setsockopt(). Le prototype diffère de celui de ma box Linux, donc au lieu de:
237
238 int yes=1;
239entrez ceci:
240
241 char yes='1';
242Comme je n'ai pas de boîtier Sun, je n'ai testé aucune des informations ci-dessus - c'est juste ce que les gens m'ont dit par e-mail.
243
244Remarque pour les programmeurs Windows
245À ce stade du guide, historiquement, j'ai fait un peu de bagging sur Windows, simplement parce que je ne l'aime pas beaucoup. Mais je devrais vraiment être juste et vous dire que Windows a une énorme base d'installation et est évidemment un système d'exploitation parfaitement bien.
246
247Ils disent que l'absence rend le cœur plus affectueux, et dans ce cas, je pense que c'est vrai. (Ou peut-être que c'est l'âge.) Mais ce que je peux dire, c'est qu'après une décennie et plus de ne pas utiliser les systèmes d'exploitation Microsoft pour mon travail personnel, je suis beaucoup plus heureux! En tant que tel, je peux m'asseoir et dire en toute sécurité: "Bien sûr, n'hésitez pas à utiliser Windows!" … Ok oui, ça me fait serrer les dents pour dire ça.
248
249Je vous encourage donc toujours à essayer plutôt Linux 1 , BSD 2 ou une version d'Unix.
250
251Mais les gens aiment ce qu'ils aiment, et vous, Windows, serez heureux de savoir que ces informations s'appliquent généralement à vous, avec quelques changements mineurs, le cas échéant.
252
253Une chose intéressante que vous pouvez faire est d'installer Cygwin 3 , qui est une collection d'outils Unix pour Windows. J'ai entendu sur la vigne que cela permet à tous ces programmes de compiler sans modification.
254
255Une autre chose que vous devriez considérer est le sous-système Windows pour Linux 4 . Cela vous permet essentiellement d'installer une chose Linux VM-ish sur Windows 10. Cela vous permettra également de vous situer.
256
257Mais certains d'entre vous voudront peut-être faire les choses à la manière de Windows pur. C'est très courageux de votre part, et voici ce que vous avez à faire: courez et obtenez Unix immédiatement! Non, non, je plaisante. Je suis censé être compatible avec Windows ces jours-ci…
258
259Voici ce que vous devrez faire (sauf si vous installez Cygwin !): Tout d'abord, ignorez à peu près tous les fichiers d'en-tête système que je mentionne ici. Tout ce que vous devez inclure est:
260
261 #include <winsock.h>
262Attendez! Vous devez également appeler WSAStartup()avant de faire quoi que ce soit d'autre avec la bibliothèque de sockets. Le code pour le faire ressemble à ceci:
263
264#include <winsock.h>
265
266{
267 WSADATA wsaData; // if this doesn't work
268 //WSAData wsaData; // then try this instead
269
270 // MAKEWORD(1,1) for Winsock 1.1, MAKEWORD(2,0) for Winsock 2.0:
271
272 if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
273 fprintf(stderr, "WSAStartup failed.\n");
274 exit(1);
275 }
276Vous devez également indiquer à votre compilateur de créer un lien dans la bibliothèque Winsock, généralement appelée wsock32.libou winsock32.lib, ou ws2_32.libpour Winsock 2.0. Sous VC ++, cela peut être fait via le Projectmenu, sous Settings.... Cliquez sur l' Linkonglet et recherchez la case intitulée «Modules objet / bibliothèque». Ajoutez «wsock32.lib» (ou la bibliothèque que vous préférez) à cette liste.
277
278Ou du moins j'entends.
279
280Enfin, vous devez appeler WSACleanup()lorsque vous avez terminé avec la bibliothèque de sockets. Consultez votre aide en ligne pour plus de détails.
281
282Une fois que vous avez fait cela, les autres exemples de ce didacticiel devraient généralement s'appliquer, à quelques exceptions près. D'une part, vous ne pouvez pas utiliser close()pour fermer un socket - vous devez utiliser à la closesocket()place. En outre, select()ne fonctionne qu'avec les descripteurs de socket, pas les descripteurs de fichiers (comme 0pour stdin).
283
284Il existe également une classe de socket que vous pouvez utiliser CSocket,. Consultez les pages d'aide de vos compilateurs pour plus d'informations.
285
286Pour obtenir plus d'informations sur Winsock, lisez la FAQ 5 de Winsock et allez-y.
287
288Enfin, j'entends dire que Windows n'a pas d' fork()appel système qui est, malheureusement, utilisé dans certains de mes exemples. Peut-être que vous devez créer un lien dans une bibliothèque POSIX ou quelque chose pour le faire fonctionner, ou vous pouvez utiliser à la CreateProcess()place. fork()ne prend aucun argument et CreateProcess()prend environ 48 milliards d'arguments. Si vous n'êtes pas à la hauteur, CreateThread()c'est un peu plus facile à digérer… malheureusement, une discussion sur le multithreading dépasse le cadre de ce document. Je ne peux que parler de tant de choses, tu sais!
289
290Politique de messagerie
291I’m generally available to help out with email questions so feel free to write in, but I can’t guarantee a response. I lead a pretty busy life and there are times when I just can’t answer a question you have. When that’s the case, I usually just delete the message. It’s nothing personal; I just won’t ever have the time to give the detailed answer you require.
292
293As a rule, the more complex the question, the less likely I am to respond. If you can narrow down your question before mailing it and be sure to include any pertinent information (like platform, compiler, error messages you’re getting, and anything else you think might help me troubleshoot), you’re much more likely to get a response. For more pointers, read ESR’s document, How To Ask Questions The Smart Way6.
294
295If you don’t get a response, hack on it some more, try to find the answer, and if it’s still elusive, then write me again with the information you’ve found and hopefully it will be enough for me to help out.
296
297Now that I’ve badgered you about how to write and not write me, I’d just like to let you know that I fully appreciate all the praise the guide has received over the years. It’s a real morale boost, and it gladdens me to hear that it is being used for good! :-) Thank you!
298
299Mirroring
300You are more than welcome to mirror this site, whether publicly or privately. If you publicly mirror the site and want me to link to it from the main page, drop me a line at beej@beej.us.
301
302Note for Translators
303If you want to translate the guide into another language, write me at beej@beej.us and I’ll link to your translation from the main page. Feel free to add your name and contact info to the translation.
304
305This source markdown document uses UTF-8 encoding.
306
307Please note the license restrictions in the Copyright, Distribution, and Legal section, below.
308
309If you want me to host the translation, just ask. I’ll also link to it if you want to host it; either way is fine.
310
311Copyright, Distribution, and Legal
312Beej’s Guide to Network Programming is Copyright © 2019 Brian “Beej Jorgensen” Hall.
313
314With specific exceptions for source code and translations, below, this work is licensed under the Creative Commons Attribution- Noncommercial- No Derivative Works 3.0 License. To view a copy of this license, visit
315
316https://creativecommons.org/licenses/by-nc-nd/3.0/
317
318or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
319
320One specific exception to the “No Derivative Works” portion of the license is as follows: this guide may be freely translated into any language, provided the translation is accurate, and the guide is reprinted in its entirety. The same license restrictions apply to the translation as to the original guide. The translation may also include the name and contact information for the translator.
321
322The C source code presented in this document is hereby granted to the public domain, and is completely free of any license restriction.
323
324Educators are freely encouraged to recommend or supply copies of this guide to their students.
325
326Unless otherwise mutually agreed by the parties in writing, the author offers the work as-is and makes no representations or warranties of any kind concerning the work, express, implied, statutory or otherwise, including, without limitation, warranties of title, merchantibility, fitness for a particular purpose, noninfringement, or the absence of latent or other defects, accuracy, or the presence of absence of errors, whether or not discoverable.
327
328Except to the extent required by applicable law, in no event will the author be liable to you on any legal theory for any special, incidental, consequential, punitive or exemplary damages arising out of the use of the work, even if the author has been advised of the possibility of such damages.
329
330Contact beej@beej.us for more information.
331
332Dedication
333Thanks to everyone who has helped in the past and future with me getting this guide written. And thank you to all the people who produce the Free software and packages that I use to make the Guide: GNU, Linux, Slackware, vim, Python, Inkscape, pandoc, many others. And finally a big thank-you to the literally thousands of you who have written in with suggestions for improvements and words of encouragement.
334
335I dedicate this guide to some of my biggest heroes and inpirators in the world of computers: Donald Knuth, Bruce Schneier, W. Richard Stevens, and The Woz, my Readership, and the entire Free and Open Source Software Community.
336
337Publishing Information
338This book is written in Markdown using the vim editor on an Arch Linux box loaded with GNU tools. The cover “art” and diagrams are produced with Inkscape. The Markdown is converted to HTML and LaTex/PDF by Python, Pandoc and XeLaTeX, using Liberation fonts. The toolchain is composed of 100% Free and Open Source Software.
339
340What is a socket?
341You hear talk of “sockets” all the time, and perhaps you are wondering just what they are exactly. Well, they’re this: a way to speak to other programs using standard Unix file descriptors.
342
343What?
344
345Ok—you may have heard some Unix hacker state, “Jeez, everything in Unix is a file!” What that person may have been talking about is the fact that when Unix programs do any sort of I/O, they do it by reading or writing to a file descriptor. A file descriptor is simply an integer associated with an open file. But (and here’s the catch), that file can be a network connection, a FIFO, a pipe, a terminal, a real on-the-disk file, or just about anything else. Everything in Unix is a file! So when you want to communicate with another program over the Internet you’re gonna do it through a file descriptor, you’d better believe it.
346
347“Where do I get this file descriptor for network communication, Mr. Smarty-Pants?” is probably the last question on your mind right now, but I’m going to answer it anyway: You make a call to the socket() system routine. It returns the socket descriptor, and you communicate through it using the specialized send() and recv() (man send, man recv) socket calls.
348
349“But, hey!” you might be exclaiming right about now. “If it’s a file descriptor, why in the name of Neptune can’t I just use the normal read() and write() calls to communicate through the socket?” The short answer is, “You can!” The longer answer is, “You can, but send() and recv() offer much greater control over your data transmission.”
350
351What next? How about this: there are all kinds of sockets. There are DARPA Internet addresses (Internet Sockets), path names on a local node (Unix Sockets), CCITT X.25 addresses (X.25 Sockets that you can safely ignore), and probably many others depending on which Unix flavor you run. This document deals only with the first: Internet Sockets.
352
353Two Types of Internet Sockets
354What’s this? There are two types of Internet sockets? Yes. Well, no. I’m lying. There are more, but I didn’t want to scare you. I’m only going to talk about two types here. Except for this sentence, where I’m going to tell you that “Raw Sockets” are also very powerful and you should look them up.
355
356All right, already. What are the two types? One is “Stream Sockets”; the other is “Datagram Sockets”, which may hereafter be referred to as “SOCK_STREAM” and “SOCK_DGRAM”, respectively. Datagram sockets are sometimes called “connectionless sockets”. (Though they can be connect()’d if you really want. See connect(), below.)
357
358Stream sockets are reliable two-way connected communication streams. If you output two items into the socket in the order “1, 2”, they will arrive in the order “1, 2” at the opposite end. They will also be error-free. I’m so certain, in fact, they will be error-free, that I’m just going to put my fingers in my ears and chant la la la la if anyone tries to claim otherwise.
359
360What uses stream sockets? Well, you may have heard of the telnet application, yes? It uses stream sockets. All the characters you type need to arrive in the same order you type them, right? Also, web browsers use the HTTP protocol which uses stream sockets to get pages. Indeed, if you telnet to a web site on port 80, and type “GET / HTTP/1.0” and hit RETURN twice, it’ll dump the HTML back at you!
361
362If you don’t have telnet installed and don’t want to install it, or your telnet is being picky about connecting to clients, the guide comes with a telnet-like program called telnot7. This should work well for all the needs of the guide. (Note that telnet is actually a spec’d networking protocol8, and telnot doesn’t implement this protocol at all.)
363
364How do stream sockets achieve this high level of data transmission quality? They use a protocol called “The Transmission Control Protocol”, otherwise known as “TCP” (see RFC 7939 for extremely detailed info on TCP). TCP makes sure your data arrives sequentially and error-free. You may have heard “TCP” before as the better half of “TCP/IP” where “IP” stands for “Internet Protocol” (see RFC 79110). IP deals primarily with Internet routing and is not generally responsible for data integrity.
365
366Cool. What about Datagram sockets? Why are they called connectionless? What is the deal, here, anyway? Why are they unreliable? Well, here are some facts: if you send a datagram, it may arrive. It may arrive out of order. If it arrives, the data within the packet will be error-free.
367
368Datagram sockets also use IP for routing, but they don’t use TCP; they use the “User Datagram Protocol”, or “UDP” (see RFC 76811).
369
370Why are they connectionless? Well, basically, it’s because you don’t have to maintain an open connection as you do with stream sockets. You just build a packet, slap an IP header on it with destination information, and send it out. No connection needed. They are generally used either when a TCP stack is unavailable or when a few dropped packets here and there don’t mean the end of the Universe. Sample applications: tftp (trivial file transfer protocol, a little brother to FTP), dhcpcd (a DHCP client), multiplayer games, streaming audio, video conferencing, etc.
371
372“Wait a minute! tftp and dhcpcd are used to transfer binary applications from one host to another! Data can’t be lost if you expect the application to work when it arrives! What kind of dark magic is this?”
373
374Well, my human friend, tftp and similar programs have their own protocol on top of UDP. For example, the tftp protocol says that for each packet that gets sent, the recipient has to send back a packet that says, “I got it!” (an “ACK” packet). If the sender of the original packet gets no reply in, say, five seconds, he’ll re-transmit the packet until he finally gets an ACK. This acknowledgment procedure is very important when implementing reliable SOCK_DGRAM applications.
375
376For unreliable applications like games, audio, or video, you just ignore the dropped packets, or perhaps try to cleverly compensate for them. (Quake players will know the manifestation this effect by the technical term: accursed lag. The word “accursed”, in this case, represents any extremely profane utterance.)
377
378Why would you use an unreliable underlying protocol? Two reasons: speed and speed. It’s way faster to fire-and-forget than it is to keep track of what has arrived safely and make sure it’s in order and all that. If you’re sending chat messages, TCP is great; if you’re sending 40 positional updates per second of the players in the world, maybe it doesn’t matter so much if one or two get dropped, and UDP is a good choice.
379
380Low level Nonsense and Network Theory
381Since I just mentioned layering of protocols, it’s time to talk about how networks really work, and to show some examples of how SOCK_DGRAM packets are built. Practically, you can probably skip this section. It’s good background, however.
382
383
384Data Encapsulation.
385Hey, kids, it’s time to learn about Data Encapsulation! This is very very important. It’s so important that you might just learn about it if you take the networks course here at Chico State ;-). Basically, it says this: a packet is born, the packet is wrapped (“encapsulated”) in a header (and rarely a footer) by the first protocol (say, the TFTP protocol), then the whole thing (TFTP header included) is encapsulated again by the next protocol (say, UDP), then again by the next (IP), then again by the final protocol on the hardware (physical) layer (say, Ethernet).
386
387When another computer receives the packet, the hardware strips the Ethernet header, the kernel strips the IP and UDP headers, the TFTP program strips the TFTP header, and it finally has the data.
388
389Now I can finally talk about the infamous Layered Network Model (aka “ISO/OSI”). This Network Model describes a system of network functionality that has many advantages over other models. For instance, you can write sockets programs that are exactly the same without caring how the data is physically transmitted (serial, thin Ethernet, AUI, whatever) because programs on lower levels deal with it for you. The actual network hardware and topology is transparent to the socket programmer.
390
391Without any further ado, I’ll present the layers of the full-blown model. Remember this for network class exams:
392
393Application
394Presentation
395Session
396Transport
397Network
398Data Link
399Physical
400The Physical Layer is the hardware (serial, Ethernet, etc.). The Application Layer is just about as far from the physical layer as you can imagine—it’s the place where users interact with the network.
401
402Now, this model is so general you could probably use it as an automobile repair guide if you really wanted to. A layered model more consistent with Unix might be:
403
404Application Layer (telnet, ftp, etc.)
405Host-to-Host Transport Layer (TCP, UDP)
406Internet Layer (IP and routing)
407Network Access Layer (Ethernet, wi-fi, or whatever)
408At this point in time, you can probably see how these layers correspond to the encapsulation of the original data.
409
410See how much work there is in building a simple packet? Jeez! And you have to type in the packet headers yourself using “cat”! Just kidding. All you have to do for stream sockets is send() the data out. All you have to do for datagram sockets is encapsulate the packet in the method of your choosing and sendto() it out. The kernel builds the Transport Layer and Internet Layer on for you and the hardware does the Network Access Layer. Ah, modern technology.
411
412So ends our brief foray into network theory. Oh yes, I forgot to tell you everything I wanted to say about routing: nothing! That’s right, I’m not going to talk about it at all. The router strips the packet to the IP header, consults its routing table, blah blah blah. Check out the IP RFC12 if you really really care. If you never learn about it, well, you’ll live.
413
414IP Addresses, structs, and Data Munging
415Here’s the part of the game where we get to talk code for a change.
416
417But first, let’s discuss more non-code! Yay! First I want to talk about IP addresses and ports for just a tad so we have that sorted out. Then we’ll talk about how the sockets API stores and manipulates IP addresses and other data.
418
419IP Addresses, versions 4 and 6
420In the good old days back when Ben Kenobi was still called Obi Wan Kenobi, there was a wonderful network routing system called The Internet Protocol Version 4, also called IPv4. It had addresses made up of four bytes (A.K.A. four “octets”), and was commonly written in “dots and numbers” form, like so: 192.0.2.111.
421
422You’ve probably seen it around.
423
424In fact, as of this writing, virtually every site on the Internet uses IPv4.
425
426Everyone, including Obi Wan, was happy. Things were great, until some naysayer by the name of Vint Cerf warned everyone that we were about to run out of IPv4 addresses!
427
428(Besides warning everyone of the Coming IPv4 Apocalypse Of Doom And Gloom, Vint Cerf13 is also well-known for being The Father Of The Internet. So I really am in no position to second-guess his judgment.)
429
430Run out of addresses? How could this be? I mean, there are like billions of IP addresses in a 32-bit IPv4 address. Do we really have billions of computers out there?
431
432Yes.
433
434Also, in the beginning, when there were only a few computers and everyone thought a billion was an impossibly large number, some big organizations were generously allocated millions of IP addresses for their own use. (Such as Xerox, MIT, Ford, HP, IBM, GE, AT&T, and some little company called Apple, to name a few.)
435
436In fact, if it weren’t for several stopgap measures, we would have run out a long time ago.
437
438But now we’re living in an era where we’re talking about every human having an IP address, every computer, every calculator, every phone, every parking meter, and (why not) every puppy dog, as well.
439
440And so, IPv6 was born. Since Vint Cerf is probably immortal (even if his physical form should pass on, heaven forbid, he is probably already existing as some kind of hyper-intelligent ELIZA14 program out in the depths of the Internet2), no one wants to have to hear him say again “I told you so” if we don’t have enough addresses in the next version of the Internet Protocol.
441
442What does this suggest to you?
443
444That we need a lot more addresses. That we need not just twice as many addresses, not a billion times as many, not a thousand trillion times as many, but 79 MILLION BILLION TRILLION times as many possible addresses! That’ll show ’em!
445
446You’re saying, “Beej, is that true? I have every reason to disbelieve large numbers.” Well, the difference between 32 bits and 128 bits might not sound like a lot; it’s only 96 more bits, right? But remember, we’re talking powers here: 32 bits represents some 4 billion numbers (232), while 128 bits represents about 340 trillion trillion trillion numbers (for real, 2128). That’s like a million IPv4 Internets for every single star in the Universe.
447
448Forget this dots-and-numbers look of IPv4, too; now we’ve got a hexadecimal representation, with each two-byte chunk separated by a colon, like this:
449
450 2001:0db8:c9d2:aee5:73e3:934a:a5ae:9551
451That’s not all! Lots of times, you’ll have an IP address with lots of zeros in it, and you can compress them between two colons. And you can leave off leading zeros for each byte pair. For instance, each of these pairs of addresses are equivalent:
452
453 2001:0db8:c9d2:0012:0000:0000:0000:0051
454 2001:db8:c9d2:12::51
455
456 2001:0db8:ab00:0000:0000:0000:0000:0000
457 2001:db8:ab00::
458
459 0000:0000:0000:0000:0000:0000:0000:0001
460 ::1
461The address ::1 is the loopback address. It always means “this machine I’m running on now”. In IPv4, the loopback address is 127.0.0.1.
462
463Finally, there’s an IPv4-compatibility mode for IPv6 addresses that you might come across. If you want, for example, to represent the IPv4 address 192.0.2.33 as an IPv6 address, you use the following notation: “::ffff:192.0.2.33”.
464
465We’re talking serious fun.
466
467In fact, it’s such serious fun, that the Creators of IPv6 have quite cavalierly lopped off trillions and trillions of addresses for reserved use, but we have so many, frankly, who’s even counting anymore? There are plenty left over for every man, woman, child, puppy, and parking meter on every planet in the galaxy. And believe me, every planet in the galaxy has parking meters. You know it’s true.
468
469Subnets
470For organizational reasons, it’s sometimes convenient to declare that "this first part of this IP address up through this bit is the network portion of the IP address, and the remainder is the host portion.
471
472For instance, with IPv4, you might have 192.0.2.12, and we could say that the first three bytes are the network and the last byte was the host. Or, put another way, we’re talking about host 12 on network 192.0.2.0 (see how we zero out the byte that was the host).
473
474And now for more outdated information! Ready? In the Ancient Times, there were “classes” of subnets, where the first one, two, or three bytes of the address was the network part. If you were lucky enough to have one byte for the network and three for the host, you could have 24 bits-worth of hosts on your network (16 million or so). That was a “Class A” network. On the opposite end was a “Class C”, with three bytes of network, and one byte of host (256 hosts, minus a couple that were reserved).
475
476So as you can see, there were just a few Class As, a huge pile of Class Cs, and some Class Bs in the middle.
477
478The network portion of the IP address is described by something called the netmask, which you bitwise-AND with the IP address to get the network number out of it. The netmask usually looks something like 255.255.255.0. (E.g. with that netmask, if your IP is 192.0.2.12, then your network is 192.0.2.12 AND 255.255.255.0 which gives 192.0.2.0.)
479
480Unfortunately, it turned out that this wasn’t fine-grained enough for the eventual needs of the Internet; we were running out of Class C networks quite quickly, and we were most definitely out of Class As, so don’t even bother to ask. To remedy this, The Powers That Be allowed for the netmask to be an arbitrary number of bits, not just 8, 16, or 24. So you might have a netmask of, say 255.255.255.252, which is 30 bits of network, and 2 bits of host allowing for four hosts on the network. (Note that the netmask is ALWAYS a bunch of 1-bits followed by a bunch of 0-bits.)
481
482But it’s a bit unwieldy to use a big string of numbers like 255.192.0.0 as a netmask. First of all, people don’t have an intuitive idea of how many bits that is, and secondly, it’s really not compact. So the New Style came along, and it’s much nicer. You just put a slash after the IP address, and then follow that by the number of network bits in decimal. Like this: 192.0.2.12/30.
483
484Or, for IPv6, something like this: 2001:db8::/32 or 2001:db8:5413:4028::9db9/64.
485
486Port Numbers
487If you’ll kindly remember, I presented you earlier with the Layered Network Model which had the Internet Layer (IP) split off from the Host-to-Host Transport Layer (TCP and UDP). Get up to speed on that before the next paragraph.
488
489Turns out that besides an IP address (used by the IP layer), there is another address that is used by TCP (stream sockets) and, coincidentally, by UDP (datagram sockets). It is the port number. It’s a 16-bit number that’s like the local address for the connection.
490
491Think of the IP address as the street address of a hotel, and the port number as the room number. That’s a decent analogy; maybe later I’ll come up with one involving the automobile industry.
492
493Say you want to have a computer that handles incoming mail AND web services—how do you differentiate between the two on a computer with a single IP address?
494
495Well, different services on the Internet have different well-known port numbers. You can see them all in the Big IANA Port List15 or, if you’re on a Unix box, in your /etc/services file. HTTP (the web) is port 80, telnet is port 23, SMTP is port 25, the game DOOM16 used port 666, etc. and so on. Ports under 1024 are often considered special, and usually require special OS privileges to use.
496
497And that’s about it!
498
499Byte Order
500By Order of the Realm! There shall be two byte orderings, hereafter to be known as Lame and Magnificent!
501
502I joke, but one really is better than the other. :-)
503
504There really is no easy way to say this, so I’ll just blurt it out: your computer might have been storing bytes in reverse order behind your back. I know! No one wanted to have to tell you.
505
506The thing is, everyone in the Internet world has generally agreed that if you want to represent the two-byte hex number, say b34f, you’ll store it in two sequential bytes b3 followed by 4f. Makes sense, and, as Wilford Brimley17 would tell you, it’s the Right Thing To Do. This number, stored with the big end first, is called Big-Endian.
507
508Unfortunately, a few computers scattered here and there throughout the world, namely anything with an Intel or Intel-compatible processor, store the bytes reversed, so b34f would be stored in memory as the sequential bytes 4f followed by b3. This storage method is called Little-Endian.
509
510But wait, I’m not done with terminology yet! The more-sane Big-Endian is also called Network Byte Order because that’s the order us network types like.
511
512Your computer stores numbers in Host Byte Order. If it’s an Intel 80x86, Host Byte Order is Little-Endian. If it’s a Motorola 68k, Host Byte Order is Big-Endian. If it’s a PowerPC, Host Byte Order is… well, it depends!
513
514A lot of times when you’re building packets or filling out data structures you’ll need to make sure your two- and four-byte numbers are in Network Byte Order. But how can you do this if you don’t know the native Host Byte Order?
515
516Good news! You just get to assume the Host Byte Order isn’t right, and you always run the value through a function to set it to Network Byte Order. The function will do the magic conversion if it has to, and this way your code is portable to machines of differing endianness.
517
518All righty. There are two types of numbers that you can convert: short (two bytes) and long (four bytes). These functions work for the unsigned variations as well. Say you want to convert a short from Host Byte Order to Network Byte Order. Start with “h” for “host”, follow it with “to”, then “n” for “network”, and “s” for “short”: h-to-n-s, or htons() (read: “Host to Network Short”).
519
520It’s almost too easy…
521
522You can use every combination of “n”, “h”, “s”, and “l” you want, not counting the really stupid ones. For example, there is NOT a stolh() (“Short to Long Host”) function—not at this party, anyway. But there are:
523
524Function Description
525htons() host to network short
526htonl() host to network long
527ntohs() network to host short
528ntohl() network to host long
529Basically, you’ll want to convert the numbers to Network Byte Order before they go out on the wire, and convert them to Host Byte Order as they come in off the wire.
530
531I don’t know of a 64-bit variant, sorry. And if you want to do floating point, check out the section on Serialization, far below.
532
533Assume the numbers in this document are in Host Byte Order unless I say otherwise.
534
535structs
536Well, we’re finally here. It’s time to talk about programming. In this section, I’ll cover various data types used by the sockets interface, since some of them are a real bear to figure out.
537
538First the easy one: a socket descriptor. A socket descriptor is the following type:
539
540 int
541Just a regular int.
542
543Things get weird from here, so just read through and bear with me.
544
545My First Struct™—struct addrinfo. This structure is a more recent invention, and is used to prep the socket address structures for subsequent use. It’s also used in host name lookups, and service name lookups. That’ll make more sense later when we get to actual usage, but just know for now that it’s one of the first things you’ll call when making a connection.
546
547 struct addrinfo {
548 int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
549 int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
550 int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
551 int ai_protocol; // use 0 for "any"
552 size_t ai_addrlen; // size of ai_addr in bytes
553 struct sockaddr *ai_addr; // struct sockaddr_in or _in6
554 char *ai_canonname; // full canonical hostname
555
556 struct addrinfo *ai_next; // linked list, next node
557 };
558You’ll load this struct up a bit, and then call getaddrinfo(). It’ll return a pointer to a new linked list of these structures filled out with all the goodies you need.
559
560You can force it to use IPv4 or IPv6 in the ai_family field, or leave it as AF_UNSPEC to use whatever. This is cool because your code can be IP version-agnostic.
561
562Note that this is a linked list: ai_next points at the next element—there could be several results for you to choose from. I’d use the first result that worked, but you might have different business needs; I don’t know everything, man!
563
564You’ll see that the ai_addr field in the struct addrinfo is a pointer to a struct sockaddr. This is where we start getting into the nitty-gritty details of what’s inside an IP address structure.
565
566You might not usually need to write to these structures; oftentimes, a call to getaddrinfo() to fill out your struct addrinfo for you is all you’ll need. You will, however, have to peer inside these structs to get the values out, so I’m presenting them here.
567
568(Also, all the code written before struct addrinfo was invented we packed all this stuff by hand, so you’ll see a lot of IPv4 code out in the wild that does exactly that. You know, in old versions of this guide and so on.)
569
570Some structs are IPv4, some are IPv6, and some are both. I’ll make notes of which are what.
571
572Anyway, the struct sockaddr holds socket address information for many types of sockets.
573
574 struct sockaddr {
575 unsigned short sa_family; // address family, AF_xxx
576 char sa_data[14]; // 14 bytes of protocol address
577 };
578sa_family can be a variety of things, but it’ll be AF_INET (IPv4) or AF_INET6 (IPv6) for everything we do in this document. sa_data contains a destination address and port number for the socket. This is rather unwieldy since you don’t want to tediously pack the address in the sa_data by hand.
579
580To deal with struct sockaddr, programmers created a parallel structure: struct sockaddr_in (“in” for “Internet”) to be used with IPv4.
581
582And this is the important bit: a pointer to a struct sockaddr_in can be cast to a pointer to a struct sockaddr and vice-versa. So even though connect() wants a struct sockaddr*, you can still use a struct sockaddr_in and cast it at the last minute!
583
584 // (IPv4 only--see struct sockaddr_in6 for IPv6)
585
586 struct sockaddr_in {
587 short int sin_family; // Address family, AF_INET
588 unsigned short int sin_port; // Port number
589 struct in_addr sin_addr; // Internet address
590 unsigned char sin_zero[8]; // Same size as struct sockaddr
591 };
592This structure makes it easy to reference elements of the socket address. Note that sin_zero (which is included to pad the structure to the length of a struct sockaddr) should be set to all zeros with the function memset(). Also, notice that sin_family corresponds to sa_family in a struct sockaddr and should be set to “AF_INET”. Finally, the sin_port must be in Network Byte Order (by using htons()!)
593
594Let’s dig deeper! You see the sin_addr field is a struct in_addr. What is that thing? Well, not to be overly dramatic, but it’s one of the scariest unions of all time:
595
596 // (IPv4 only--see struct in6_addr for IPv6)
597
598 // Internet address (a structure for historical reasons)
599 struct in_addr {
600 uint32_t s_addr; // that's a 32-bit int (4 bytes)
601 };
602Whoa! Well, it used to be a union, but now those days seem to be gone. Good riddance. So if you have declared ina to be of type struct sockaddr_in, then ina.sin_addr.s_addr references the 4-byte IP address (in Network Byte Order). Note that even if your system still uses the God-awful union for struct in_addr, you can still reference the 4-byte IP address in exactly the same way as I did above (this due to #defines).
603
604What about IPv6? Similar structs exist for it, as well:
605
606 // (IPv6 only--see struct sockaddr_in and struct in_addr for IPv4)
607
608 struct sockaddr_in6 {
609 u_int16_t sin6_family; // address family, AF_INET6
610 u_int16_t sin6_port; // port number, Network Byte Order
611 u_int32_t sin6_flowinfo; // IPv6 flow information
612 struct in6_addr sin6_addr; // IPv6 address
613 u_int32_t sin6_scope_id; // Scope ID
614 };
615
616 struct in6_addr {
617 unsigned char s6_addr[16]; // IPv6 address
618 };
619Note that IPv6 has an IPv6 address and a port number, just like IPv4 has an IPv4 address and a port number.
620
621Also note that I’m not going to talk about the IPv6 flow information or Scope ID fields for the moment… this is just a starter guide. :-)
622
623Last but not least, here is another simple structure, struct sockaddr_storage that is designed to be large enough to hold both IPv4 and IPv6 structures. See, for some calls, sometimes you don’t know in advance if it’s going to fill out your struct sockaddr with an IPv4 or IPv6 address. So you pass in this parallel structure, very similar to struct sockaddr except larger, and then cast it to the type you need:
624
625 struct sockaddr_storage {
626 sa_family_t ss_family; // address family
627
628 // all this is padding, implementation specific, ignore it:
629 char __ss_pad1[_SS_PAD1SIZE];
630 int64_t __ss_align;
631 char __ss_pad2[_SS_PAD2SIZE];
632 };
633What’s important is that you can see the address family in the ss_family field—check this to see if it’s AF_INET or AF_INET6 (for IPv4 or IPv6). Then you can cast it to a struct sockaddr_in or struct sockaddr_in6 if you wanna.
634
635IP Addresses, Part Deux
636Fortunately for you, there are a bunch of functions that allow you to manipulate IP addresses. No need to figure them out by hand and stuff them in a long with the << operator.
637
638First, let’s say you have a struct sockaddr_in ina, and you have an IP address “10.12.110.57” or “2001:db8:63b3:1::3490” that you want to store into it. The function you want to use, inet_pton(), converts an IP address in numbers-and-dots notation into either a struct in_addr or a struct in6_addr depending on whether you specify AF_INET or AF_INET6. (“pton” stands for “presentation to network”—you can call it “printable to network” if that’s easier to remember.) The conversion can be made as follows:
639
640 struct sockaddr_in sa; // IPv4
641 struct sockaddr_in6 sa6; // IPv6
642
643 inet_pton(AF_INET, "10.12.110.57", &(sa.sin_addr)); // IPv4
644 inet_pton(AF_INET6, "2001:db8:63b3:1::3490", &(sa6.sin6_addr)); // IPv6
645(Quick note: the old way of doing things used a function called inet_addr() or another function called inet_aton(); these are now obsolete and don’t work with IPv6.)
646
647Now, the above code snippet isn’t very robust because there is no error checking. See, inet_pton() returns -1 on error, or 0 if the address is messed up. So check to make sure the result is greater than 0 before using!
648
649All right, now you can convert string IP addresses to their binary representations. What about the other way around? What if you have a struct in_addr and you want to print it in numbers-and-dots notation? (Or a struct in6_addr that you want in, uh, “hex-and-colons” notation.) In this case, you’ll want to use the function inet_ntop() (“ntop” means “network to presentation”—you can call it “network to printable” if that’s easier to remember), like this:
650
651// IPv4:
652
653char ip4[INET_ADDRSTRLEN]; // space to hold the IPv4 string
654struct sockaddr_in sa; // pretend this is loaded with something
655
656inet_ntop(AF_INET, &(sa.sin_addr), ip4, INET_ADDRSTRLEN);
657
658printf("The IPv4 address is: %s\n", ip4);
659
660
661// IPv6:
662
663char ip6[INET6_ADDRSTRLEN]; // space to hold the IPv6 string
664struct sockaddr_in6 sa6; // pretend this is loaded with something
665
666inet_ntop(AF_INET6, &(sa6.sin6_addr), ip6, INET6_ADDRSTRLEN);
667
668printf("The address is: %s\n", ip6);
669When you call it, you’ll pass the address type (IPv4 or IPv6), the address, a pointer to a string to hold the result, and the maximum length of that string. (Two macros conveniently hold the size of the string you’ll need to hold the largest IPv4 or IPv6 address: INET_ADDRSTRLEN and INET6_ADDRSTRLEN.)
670
671(Another quick note to mention once again the old way of doing things: the historical function to do this conversion was called inet_ntoa(). It’s also obsolete and won’t work with IPv6.)
672
673Lastly, these functions only work with numeric IP addresses—they won’t do any nameserver DNS lookup on a hostname, like “www.example.com”. You will use getaddrinfo() to do that, as you’ll see later on.
674
675Private (Or Disconnected) Networks
676Lots of places have a firewall that hides the network from the rest of the world for their own protection. And often times, the firewall translates “internal” IP addresses to “external” (that everyone else in the world knows) IP addresses using a process called Network Address Translation, or NAT.
677
678Are you getting nervous yet? “Where’s he going with all this weird stuff?”
679
680Well, relax and buy yourself a non-alcoholic (or alcoholic) drink, because as a beginner, you don’t even have to worry about NAT, since it’s done for you transparently. But I wanted to talk about the network behind the firewall in case you started getting confused by the network numbers you were seeing.
681
682For instance, I have a firewall at home. I have two static IPv4 addresses allocated to me by the DSL company, and yet I have seven computers on the network. How is this possible? Two computers can’t share the same IP address, or else the data wouldn’t know which one to go to!
683
684The answer is: they don’t share the same IP addresses. They are on a private network with 24 million IP addresses allocated to it. They are all just for me. Well, all for me as far as anyone else is concerned. Here’s what’s happening:
685
686If I log into a remote computer, it tells me I’m logged in from 192.0.2.33 which is the public IP address my ISP has provided to me. But if I ask my local computer what its IP address is, it says 10.0.0.5. Who is translating the IP address from one to the other? That’s right, the firewall! It’s doing NAT!
687
68810.x.x.x is one of a few reserved networks that are only to be used either on fully disconnected networks, or on networks that are behind firewalls. The details of which private network numbers are available for you to use are outlined in RFC 191818, but some common ones you’ll see are 10.x.x.x and 192.168.x.x, where x is 0-255, generally. Less common is 172.y.x.x, where y goes between 16 and 31.
689
690Networks behind a NATing firewall don’t need to be on one of these reserved networks, but they commonly are.
691
692(Fun fact! My external IP address isn’t really 192.0.2.33. The 192.0.2.x network is reserved for make-believe “real” IP addresses to be used in documentation, just like this guide! Wowzers!)
693
694IPv6 has private networks, too, in a sense. They’ll start with fdXX: (or maybe in the future fcXX:), as per RFC 419319. NAT and IPv6 don’t generally mix, however (unless you’re doing the IPv6 to IPv4 gateway thing which is beyond the scope of this document)—in theory you’ll have so many addresses at your disposal that you won’t need to use NAT any longer. But if you want to allocate addresses for yourself on a network that won’t route outside, this is how to do it.
695
696Jumping from IPv4 to IPv6
697But I just want to know what to change in my code to get it going with IPv6! Tell me now!
698
699Ok! Ok!
700
701Almost everything in here is something I’ve gone over, above, but it’s the short version for the impatient. (Of course, there is more than this, but this is what applies to the guide.)
702
703First of all, try to use getaddrinfo() to get all the struct sockaddr info, instead of packing the structures by hand. This will keep you IP version-agnostic, and will eliminate many of the subsequent steps.
704
705Any place that you find you’re hard-coding anything related to the IP version, try to wrap up in a helper function.
706
707Change AF_INET to AF_INET6.
708
709Change PF_INET to PF_INET6.
710
711Change INADDR_ANY assignments to in6addr_any assignments, which are slightly different:
712
713 struct sockaddr_in sa;
714 struct sockaddr_in6 sa6;
715
716 sa.sin_addr.s_addr = INADDR_ANY; // use my IPv4 address
717 sa6.sin6_addr = in6addr_any; // use my IPv6 address
718Also, the value IN6ADDR_ANY_INIT can be used as an initializer when the struct in6_addr is declared, like so:
719
720 struct in6_addr ia6 = IN6ADDR_ANY_INIT;
721Instead of struct sockaddr_in use struct sockaddr_in6, being sure to add “6” to the fields as appropriate (see structs, above). There is no sin6_zero field.
722
723Instead of struct in_addr use struct in6_addr, being sure to add “6” to the fields as appropriate (see structs, above).
724
725Instead of inet_aton() or inet_addr(), use inet_pton().
726
727Instead of inet_ntoa(), use inet_ntop().
728
729Instead of gethostbyname(), use the superior getaddrinfo().
730
731Instead of gethostbyaddr(), use the superior getnameinfo() (although gethostbyaddr() can still work with IPv6).
732
733INADDR_BROADCAST no longer works. Use IPv6 multicast instead.
734
735Et voila!
736
737System Calls or Bust
738This is the section where we get into the system calls (and other library calls) that allow you to access the network functionality of a Unix box, or any box that supports the sockets API for that matter (BSD, Windows, Linux, Mac, what-have-you.) When you call one of these functions, the kernel takes over and does all the work for you automagically.
739
740The place most people get stuck around here is what order to call these things in. In that, the man pages are no use, as you’ve probably discovered. Well, to help with that dreadful situation, I’ve tried to lay out the system calls in the following sections in exactly (approximately) the same order that you’ll need to call them in your programs.
741
742That, coupled with a few pieces of sample code here and there, some milk and cookies (which I fear you will have to supply yourself), and some raw guts and courage, and you’ll be beaming data around the Internet like the Son of Jon Postel!
743
744(Please note that for brevity, many code snippets below do not include necessary error checking. And they very commonly assume that the result from calls to getaddrinfo() succeed and return a valid entry in the linked list. Both of these situations are properly addressed in the stand-alone programs, though, so use those as a model.)
745
746getaddrinfo()—Prepare to launch!
747This is a real workhorse of a function with a lot of options, but usage is actually pretty simple. It helps set up the structs you need later on.
748
749A tiny bit of history: it used to be that you would use a function called gethostbyname() to do DNS lookups. Then you’d load that information by hand into a struct sockaddr_in, and use that in your calls.
750
751This is no longer necessary, thankfully. (Nor is it desirable, if you want to write code that works for both IPv4 and IPv6!) In these modern times, you now have the function getaddrinfo() that does all kinds of good stuff for you, including DNS and service name lookups, and fills out the structs you need, besides!
752
753Let’s take a look!
754
755 #include <sys/types.h>
756 #include <sys/socket.h>
757 #include <netdb.h>
758
759 int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
760 const char *service, // e.g. "http" or port number
761 const struct addrinfo *hints,
762 struct addrinfo **res);
763You give this function three input parameters, and it gives you a pointer to a linked-list, res, of results.
764
765The node parameter is the host name to connect to, or an IP address.
766
767Next is the parameter service, which can be a port number, like “80”, or the name of a particular service (found in The IANA Port List20 or the /etc/services file on your Unix machine) like “http” or “ftp” or “telnet” or “smtp” or whatever.
768
769Finally, the hints parameter points to a struct addrinfo that you’ve already filled out with relevant information.
770
771Here’s a sample call if you’re a server who wants to listen on your host’s IP address, port 3490. Note that this doesn’t actually do any listening or network setup; it merely sets up structures we’ll use later:
772
773int status;
774struct addrinfo hints;
775struct addrinfo *servinfo; // will point to the results
776
777memset(&hints, 0, sizeof hints); // make sure the struct is empty
778hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6
779hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
780hints.ai_flags = AI_PASSIVE; // fill in my IP for me
781
782if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {
783 fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
784 exit(1);
785}
786
787// servinfo now points to a linked list of 1 or more struct addrinfos
788
789// ... do everything until you don't need servinfo anymore ....
790
791freeaddrinfo(servinfo); // free the linked-list
792Notice that I set the ai_family to AF_UNSPEC, thereby saying that I don’t care if we use IPv4 or IPv6. You can set it to AF_INET or AF_INET6 if you want one or the other specifically.
793
794Also, you’ll see the AI_PASSIVE flag in there; this tells getaddrinfo() to assign the address of my local host to the socket structures. This is nice because then you don’t have to hardcode it. (Or you can put a specific address in as the first parameter to getaddrinfo() where I currently have NULL, up there.)
795
796Then we make the call. If there’s an error (getaddrinfo() returns non-zero), we can print it out using the function gai_strerror(), as you see. If everything works properly, though, servinfo will point to a linked list of struct addrinfos, each of which contains a struct sockaddr of some kind that we can use later! Nifty!
797
798Finally, when we’re eventually all done with the linked list that getaddrinfo() so graciously allocated for us, we can (and should) free it all up with a call to freeaddrinfo().
799
800Here’s a sample call if you’re a client who wants to connect to a particular server, say “www.example.net” port 3490. Again, this doesn’t actually connect, but it sets up the structures we’ll use later:
801
802int status;
803struct addrinfo hints;
804struct addrinfo *servinfo; // will point to the results
805
806memset(&hints, 0, sizeof hints); // make sure the struct is empty
807hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6
808hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
809
810// get ready to connect
811status = getaddrinfo("www.example.net", "3490", &hints, &servinfo);
812
813// servinfo now points to a linked list of 1 or more struct addrinfos
814
815// etc.
816I keep saying that servinfo is a linked list with all kinds of address information. Let’s write a quick demo program to show off this information. This short program21 will print the IP addresses for whatever host you specify on the command line:
817
818/*
819** showip.c -- show IP addresses for a host given on the command line
820*/
821
822#include <stdio.h>
823#include <string.h>
824#include <sys/types.h>
825#include <sys/socket.h>
826#include <netdb.h>
827#include <arpa/inet.h>
828#include <netinet/in.h>
829
830int main(int argc, char *argv[])
831{
832 struct addrinfo hints, *res, *p;
833 int status;
834 char ipstr[INET6_ADDRSTRLEN];
835
836 if (argc != 2) {
837 fprintf(stderr,"usage: showip hostname\n");
838 return 1;
839 }
840
841 memset(&hints, 0, sizeof hints);
842 hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
843 hints.ai_socktype = SOCK_STREAM;
844
845 if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
846 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
847 return 2;
848 }
849
850 printf("IP addresses for %s:\n\n", argv[1]);
851
852 for(p = res;p != NULL; p = p->ai_next) {
853 void *addr;
854 char *ipver;
855
856 // get the pointer to the address itself,
857 // different fields in IPv4 and IPv6:
858 if (p->ai_family == AF_INET) { // IPv4
859 struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
860 addr = &(ipv4->sin_addr);
861 ipver = "IPv4";
862 } else { // IPv6
863 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
864 addr = &(ipv6->sin6_addr);
865 ipver = "IPv6";
866 }
867
868 // convert the IP to a string and print it:
869 inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
870 printf(" %s: %s\n", ipver, ipstr);
871 }
872
873 freeaddrinfo(res); // free the linked list
874
875 return 0;
876}
877As you see, the code calls getaddrinfo() on whatever you pass on the command line, that fills out the linked list pointed to by res, and then we can iterate over the list and print stuff out or do whatever.
878
879(There’s a little bit of ugliness there where we have to dig into the different types of struct sockaddrs depending on the IP version. Sorry about that! I’m not sure of a better way around it.)
880
881Sample run! Everyone loves screenshots:
882
883 $ showip www.example.net
884 IP addresses for www.example.net:
885
886 IPv4: 192.0.2.88
887
888 $ showip ipv6.example.com
889 IP addresses for ipv6.example.com:
890
891 IPv4: 192.0.2.101
892 IPv6: 2001:db8:8c00:22::171
893Now that we have that under control, we’ll use the results we get from getaddrinfo() to pass to other socket functions and, at long last, get our network connection established! Keep reading!
894
895socket()—Get the File Descriptor!
896I guess I can put it off no longer—I have to talk about the socket() system call. Here’s the breakdown:
897
898 #include <sys/types.h>
899 #include <sys/socket.h>
900
901 int socket(int domain, int type, int protocol);
902But what are these arguments? They allow you to say what kind of socket you want (IPv4 or IPv6, stream or datagram, and TCP or UDP).
903
904It used to be people would hardcode these values, and you can absolutely still do that. (domain is PF_INET or PF_INET6, type is SOCK_STREAM or SOCK_DGRAM, and protocol can be set to 0 to choose the proper protocol for the given type. Or you can call getprotobyname() to look up the protocol you want, “tcp” or “udp”.)
905
906(This PF_INET thing is a close relative of the AF_INET that you can use when initializing the sin_family field in your struct sockaddr_in. In fact, they’re so closely related that they actually have the same value, and many programmers will call socket() and pass AF_INET as the first argument instead of PF_INET. Now, get some milk and cookies, because it’s time for a story. Once upon a time, a long time ago, it was thought that maybe an address family (what the “AF” in “AF_INET” stands for) might support several protocols that were referred to by their protocol family (what the “PF” in “PF_INET” stands for). That didn’t happen. And they all lived happily ever after, The End. So the most correct thing to do is to use AF_INET in your struct sockaddr_in and PF_INET in your call to socket().)
907
908Anyway, enough of that. What you really want to do is use the values from the results of the call to getaddrinfo(), and feed them into socket() directly like this:
909
910int s;
911struct addrinfo hints, *res;
912
913// do the lookup
914// [pretend we already filled out the "hints" struct]
915getaddrinfo("www.example.com", "http", &hints, &res);
916
917// again, you should do error-checking on getaddrinfo(), and walk
918// the "res" linked list looking for valid entries instead of just
919// assuming the first one is good (like many of these examples do).
920// See the section on client/server for real examples.
921
922s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
923socket() simply returns to you a socket descriptor that you can use in later system calls, or -1 on error. The global variable errno is set to the error’s value (see the errno man page for more details, and a quick note on using errno in multithreaded programs).
924
925Fine, fine, fine, but what good is this socket? The answer is that it’s really no good by itself, and you need to read on and make more system calls for it to make any sense.
926
927bind()—What port am I on?
928Once you have a socket, you might have to associate that socket with a port on your local machine. (This is commonly done if you’re going to listen() for incoming connections on a specific port—multiplayer network games do this when they tell you to “connect to 192.168.5.10 port 3490”.) The port number is used by the kernel to match an incoming packet to a certain process’s socket descriptor. If you’re going to only be doing a connect() (because you’re the client, not the server), this is probably be unnecessary. Read it anyway, just for kicks.
929
930Here is the synopsis for the bind() system call:
931
932 #include <sys/types.h>
933 #include <sys/socket.h>
934
935 int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
936sockfd is the socket file descriptor returned by socket(). my_addr is a pointer to a struct sockaddr that contains information about your address, namely, port and IP address. addrlen is the length in bytes of that address.
937
938Whew. That’s a bit to absorb in one chunk. Let’s have an example that binds the socket to the host the program is running on, port 3490:
939
940struct addrinfo hints, *res;
941int sockfd;
942
943// first, load up address structs with getaddrinfo():
944
945memset(&hints, 0, sizeof hints);
946hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
947hints.ai_socktype = SOCK_STREAM;
948hints.ai_flags = AI_PASSIVE; // fill in my IP for me
949
950getaddrinfo(NULL, "3490", &hints, &res);
951
952// make a socket:
953
954sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
955
956// bind it to the port we passed in to getaddrinfo():
957
958bind(sockfd, res->ai_addr, res->ai_addrlen);
959By using the AI_PASSIVE flag, I’m telling the program to bind to the IP of the host it’s running on. If you want to bind to a specific local IP address, drop the AI_PASSIVE and put an IP address in for the first argument to getaddrinfo().
960
961bind() also returns -1 on error and sets errno to the error’s value.
962
963Lots of old code manually packs the struct sockaddr_in before calling bind(). Obviously this is IPv4-specific, but there’s really nothing stopping you from doing the same thing with IPv6, except that using getaddrinfo() is going to be easier, generally. Anyway, the old code looks something like this:
964
965// !!! THIS IS THE OLD WAY !!!
966
967int sockfd;
968struct sockaddr_in my_addr;
969
970sockfd = socket(PF_INET, SOCK_STREAM, 0);
971
972my_addr.sin_family = AF_INET;
973my_addr.sin_port = htons(MYPORT); // short, network byte order
974my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
975memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
976
977bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr);
978In the above code, you could also assign INADDR_ANY to the s_addr field if you wanted to bind to your local IP address (like the AI_PASSIVE flag, above). The IPv6 version of INADDR_ANY is a global variable in6addr_any that is assigned into the sin6_addr field of your struct sockaddr_in6. (There is also a macro IN6ADDR_ANY_INIT that you can use in a variable initializer.)
979
980Another thing to watch out for when calling bind(): don’t go underboard with your port numbers. All ports below 1024 are RESERVED (unless you’re the superuser)! You can have any port number above that, right up to 65535 (provided they aren’t already being used by another program).
981
982Sometimes, you might notice, you try to rerun a server and bind() fails, claiming “Address already in use.” What does that mean? Well, a little bit of a socket that was connected is still hanging around in the kernel, and it’s hogging the port. You can either wait for it to clear (a minute or so), or add code to your program allowing it to reuse the port, like this:
983
984int yes=1;
985//char yes='1'; // Solaris people use this
986
987// lose the pesky "Address already in use" error message
988if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof yes) == -1) {
989 perror("setsockopt");
990 exit(1);
991}
992One small extra final note about bind(): there are times when you won’t absolutely have to call it. If you are connect()ing to a remote machine and you don’t care what your local port is (as is the case with telnet where you only care about the remote port), you can simply call connect(), it’ll check to see if the socket is unbound, and will bind() it to an unused local port if necessary.
993
994connect()—Hey, you!
995Let’s just pretend for a few minutes that you’re a telnet application. Your user commands you (just like in the movie TRON) to get a socket file descriptor. You comply and call socket(). Next, the user tells you to connect to “10.12.110.57” on port “23” (the standard telnet port). Yow! What do you do now?
996
997Lucky for you, program, you’re now perusing the section on connect()—how to connect to a remote host. So read furiously onward! No time to lose!
998
999The connect() call is as follows:
1000
1001 #include <sys/types.h>
1002 #include <sys/socket.h>
1003
1004 int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
1005sockfd is our friendly neighborhood socket file descriptor, as returned by the socket() call, serv_addr is a struct sockaddr containing the destination port and IP address, and addrlen is the length in bytes of the server address structure.
1006
1007All of this information can be gleaned from the results of the getaddrinfo() call, which rocks.
1008
1009Is this starting to make more sense? I can’t hear you from here, so I’ll just have to hope that it is. Let’s have an example where we make a socket connection to “www.example.com”, port 3490:
1010
1011struct addrinfo hints, *res;
1012int sockfd;
1013
1014// first, load up address structs with getaddrinfo():
1015
1016memset(&hints, 0, sizeof hints);
1017hints.ai_family = AF_UNSPEC;
1018hints.ai_socktype = SOCK_STREAM;
1019
1020getaddrinfo("www.example.com", "3490", &hints, &res);
1021
1022// make a socket:
1023
1024sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
1025
1026// connect!
1027
1028connect(sockfd, res->ai_addr, res->ai_addrlen);
1029Again, old-school programs filled out their own struct sockaddr_ins to pass to connect(). You can do that if you want to. See the similar note in the bind() section, above.
1030
1031Be sure to check the return value from connect()—it’ll return -1 on error and set the variable errno.
1032
1033Also, notice that we didn’t call bind(). Basically, we don’t care about our local port number; we only care where we’re going (the remote port). The kernel will choose a local port for us, and the site we connect to will automatically get this information from us. No worries.
1034
1035listen()—Will somebody please call me?
1036Ok, time for a change of pace. What if you don’t want to connect to a remote host. Say, just for kicks, that you want to wait for incoming connections and handle them in some way. The process is two step: first you listen(), then you accept() (see below).
1037
1038The listen call is fairly simple, but requires a bit of explanation:
1039
1040 int listen(int sockfd, int backlog);
1041sockfd is the usual socket file descriptor from the socket() system call. backlog is the number of connections allowed on the incoming queue. What does that mean? Well, incoming connections are going to wait in this queue until you accept() them (see below) and this is the limit on how many can queue up. Most systems silently limit this number to about 20; you can probably get away with setting it to 5 or 10.
1042
1043Again, as per usual, listen() returns -1 and sets errno on error.
1044
1045Well, as you can probably imagine, we need to call bind() before we call listen() so that the server is running on a specific port. (You have to be able to tell your buddies which port to connect to!) So if you’re going to be listening for incoming connections, the sequence of system calls you’ll make is:
1046
1047getaddrinfo();
1048socket();
1049bind();
1050listen();
1051/* accept() goes here */
1052I’ll just leave that in the place of sample code, since it’s fairly self-explanatory. (The code in the accept() section, below, is more complete.) The really tricky part of this whole sha-bang is the call to accept().
1053
1054accept()—“Thank you for calling port 3490.”
1055Get ready—the accept() call is kinda weird! What’s going to happen is this: someone far far away will try to connect() to your machine on a port that you are listen()ing on. Their connection will be queued up waiting to be accept()ed. You call accept() and you tell it to get the pending connection. It’ll return to you a brand new socket file descriptor to use for this single connection! That’s right, suddenly you have two socket file descriptors for the price of one! The original one is still listening for more new connections, and the newly created one is finally ready to send() and recv(). We’re there!
1056
1057The call is as follows:
1058
1059 #include <sys/types.h>
1060 #include <sys/socket.h>
1061
1062 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
1063sockfd is the listen()ing socket descriptor. Easy enough. addr will usually be a pointer to a local struct sockaddr_storage. This is where the information about the incoming connection will go (and with it you can determine which host is calling you from which port). addrlen is a local integer variable that should be set to sizeof(struct sockaddr_storage) before its address is passed to accept(). accept() will not put more than that many bytes into addr. If it puts fewer in, it’ll change the value of addrlen to reflect that.
1064
1065Guess what? accept() returns -1 and sets errno if an error occurs. Betcha didn’t figure that.
1066
1067Like before, this is a bunch to absorb in one chunk, so here’s a sample code fragment for your perusal:
1068
1069#include <string.h>
1070#include <sys/types.h>
1071#include <sys/socket.h>
1072#include <netinet/in.h>
1073
1074#define MYPORT "3490" // the port users will be connecting to
1075#define BACKLOG 10 // how many pending connections queue will hold
1076
1077int main(void)
1078{
1079 struct sockaddr_storage their_addr;
1080 socklen_t addr_size;
1081 struct addrinfo hints, *res;
1082 int sockfd, new_fd;
1083
1084 // !! don't forget your error checking for these calls !!
1085
1086 // first, load up address structs with getaddrinfo():
1087
1088 memset(&hints, 0, sizeof hints);
1089 hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
1090 hints.ai_socktype = SOCK_STREAM;
1091 hints.ai_flags = AI_PASSIVE; // fill in my IP for me
1092
1093 getaddrinfo(NULL, MYPORT, &hints, &res);
1094
1095 // make a socket, bind it, and listen on it:
1096
1097 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
1098 bind(sockfd, res->ai_addr, res->ai_addrlen);
1099 listen(sockfd, BACKLOG);
1100
1101 // now accept an incoming connection:
1102
1103 addr_size = sizeof their_addr;
1104 new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
1105
1106 // ready to communicate on socket descriptor new_fd!
1107 .
1108 .
1109 .
1110Again, note that we will use the socket descriptor new_fd for all send() and recv() calls. If you’re only getting one single connection ever, you can close() the listening sockfd in order to prevent more incoming connections on the same port, if you so desire.
1111
1112send() and recv()—Talk to me, baby!
1113These two functions are for communicating over stream sockets or connected datagram sockets. If you want to use regular unconnected datagram sockets, you’ll need to see the section on sendto() and recvfrom(), below.
1114
1115The send() call:
1116
1117 int send(int sockfd, const void *msg, int len, int flags);
1118sockfd is the socket descriptor you want to send data to (whether it’s the one returned by socket() or the one you got with accept()). msg is a pointer to the data you want to send, and len is the length of that data in bytes. Just set flags to 0. (See the send() man page for more information concerning flags.)
1119
1120Some sample code might be:
1121
1122char *msg = "Beej was here!";
1123int len, bytes_sent;
1124.
1125.
1126.
1127len = strlen(msg);
1128bytes_sent = send(sockfd, msg, len, 0);
1129.
1130.
1131.
1132send() returns the number of bytes actually sent out—this might be less than the number you told it to send! See, sometimes you tell it to send a whole gob of data and it just can’t handle it. It’ll fire off as much of the data as it can, and trust you to send the rest later. Remember, if the value returned by send() doesn’t match the value in len, it’s up to you to send the rest of the string. The good news is this: if the packet is small (less than 1K or so) it will probably manage to send the whole thing all in one go. Again, -1 is returned on error, and errno is set to the error number.
1133
1134The recv() call is similar in many respects:
1135
1136 int recv(int sockfd, void *buf, int len, int flags);
1137sockfd is the socket descriptor to read from, buf is the buffer to read the information into, len is the maximum length of the buffer, and flags can again be set to 0. (See the recv() man page for flag information.)
1138
1139recv() returns the number of bytes actually read into the buffer, or -1 on error (with errno set, accordingly).
1140
1141Wait! recv() can return 0. This can mean only one thing: the remote side has closed the connection on you! A return value of 0 is recv()’s way of letting you know this has occurred.
1142
1143There, that was easy, wasn’t it? You can now pass data back and forth on stream sockets! Whee! You’re a Unix Network Programmer!
1144
1145sendto() and recvfrom()—Talk to me, DGRAM-style
1146“This is all fine and dandy,” I hear you saying, “but where does this leave me with unconnected datagram sockets?” No problemo, amigo. We have just the thing.
1147
1148Since datagram sockets aren’t connected to a remote host, guess which piece of information we need to give before we send a packet? That’s right! The destination address! Here’s the scoop:
1149
1150 int sendto(int sockfd, const void *msg, int len, unsigned int flags,
1151 const struct sockaddr *to, socklen_t tolen);
1152As you can see, this call is basically the same as the call to send() with the addition of two other pieces of information. to is a pointer to a struct sockaddr (which will probably be another struct sockaddr_in or struct sockaddr_in6 or struct sockaddr_storage that you cast at the last minute) which contains the destination IP address and port. tolen, an int deep-down, can simply be set to sizeof *to or sizeof(struct sockaddr_storage).
1153
1154To get your hands on the destination address structure, you’ll probably either get it from getaddrinfo(), or from recvfrom(), below, or you’ll fill it out by hand.
1155
1156Just like with send(), sendto() returns the number of bytes actually sent (which, again, might be less than the number of bytes you told it to send!), or -1 on error.
1157
1158Equally similar are recv() and recvfrom(). The synopsis of recvfrom() is:
1159
1160 int recvfrom(int sockfd, void *buf, int len, unsigned int flags,
1161 struct sockaddr *from, int *fromlen);
1162Again, this is just like recv() with the addition of a couple fields. from is a pointer to a local struct sockaddr_storage that will be filled with the IP address and port of the originating machine. fromlen is a pointer to a local int that should be initialized to sizeof *from or sizeof(struct sockaddr_storage). When the function returns, fromlen will contain the length of the address actually stored in from.
1163
1164recvfrom() returns the number of bytes received, or -1 on error (with errno set accordingly).
1165
1166So, here’s a question: why do we use struct sockaddr_storage as the socket type? Why not struct sockaddr_in? Because, you see, we want to not tie ourselves down to IPv4 or IPv6. So we use the generic struct sockaddr_storage which we know will be big enough for either.
1167
1168(So… here’s another question: why isn’t struct sockaddr itself big enough for any address? We even cast the general-purpose struct sockaddr_storage to the general-purpose struct sockaddr! Seems extraneous and redundant, huh. The answer is, it just isn’t big enough, and I’d guess that changing it at this point would be Problematic. So they made a new one.)
1169
1170Remember, if you connect() a datagram socket, you can then simply use send() and recv() for all your transactions. The socket itself is still a datagram socket and the packets still use UDP, but the socket interface will automatically add the destination and source information for you.
1171
1172close() and shutdown()—Get outta my face!
1173Whew! You’ve been send()ing and recv()ing data all day long, and you’ve had it. You’re ready to close the connection on your socket descriptor. This is easy. You can just use the regular Unix file descriptor close() function:
1174
1175 close(sockfd);
1176This will prevent any more reads and writes to the socket. Anyone attempting to read or write the socket on the remote end will receive an error.
1177
1178Just in case you want a little more control over how the socket closes, you can use the shutdown() function. It allows you to cut off communication in a certain direction, or both ways (just like close() does). Synopsis:
1179
1180 int shutdown(int sockfd, int how);
1181sockfd is the socket file descriptor you want to shutdown, and how is one of the following:
1182
1183how Effect
11840 Further receives are disallowed
11851 Further sends are disallowed
11862 Further sends and receives are disallowed (like close())
1187shutdown() returns 0 on success, and -1 on error (with errno set accordingly).
1188
1189If you deign to use shutdown() on unconnected datagram sockets, it will simply make the socket unavailable for further send() and recv() calls (remember that you can use these if you connect() your datagram socket).
1190
1191It’s important to note that shutdown() doesn’t actually close the file descriptor—it just changes its usability. To free a socket descriptor, you need to use close().
1192
1193Nothing to it.
1194
1195(Except to remember that if you’re using Windows and Winsock that you should call closesocket() instead of close().)
1196
1197getpeername()—Who are you?
1198This function is so easy.
1199
1200It’s so easy, I almost didn’t give it its own section. But here it is anyway.
1201
1202The function getpeername() will tell you who is at the other end of a connected stream socket. The synopsis:
1203
1204 #include <sys/socket.h>
1205
1206 int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);
1207sockfd is the descriptor of the connected stream socket, addr is a pointer to a struct sockaddr (or a struct sockaddr_in) that will hold the information about the other side of the connection, and addrlen is a pointer to an int, that should be initialized to sizeof *addr or sizeof(struct sockaddr).
1208
1209The function returns -1 on error and sets errno accordingly.
1210
1211Once you have their address, you can use inet_ntop(), getnameinfo(), or gethostbyaddr() to print or get more information. No, you can’t get their login name. (Ok, ok. If the other computer is running an ident daemon, this is possible. This, however, is beyond the scope of this document. Check out RFC 141322 for more info.)
1212
1213gethostname()—Who am I?
1214Even easier than getpeername() is the function gethostname(). It returns the name of the computer that your program is running on. The name can then be used by gethostbyname(), below, to determine the IP address of your local machine.
1215
1216What could be more fun? I could think of a few things, but they don’t pertain to socket programming. Anyway, here’s the breakdown:
1217
1218 #include <unistd.h>
1219
1220 int gethostname(char *hostname, size_t size);
1221The arguments are simple: hostname is a pointer to an array of chars that will contain the hostname upon the function’s return, and size is the length in bytes of the hostname array.
1222
1223The function returns 0 on successful completion, and -1 on error, setting errno as usual.
1224
1225Client-Server Background
1226It’s a client-server world, baby. Just about everything on the network deals with client processes talking to server processes and vice-versa. Take telnet, for instance. When you connect to a remote host on port 23 with telnet (the client), a program on that host (called telnetd, the server) springs to life. It handles the incoming telnet connection, sets you up with a login prompt, etc.
1227
1228
1229Client-Server Interaction.
1230The exchange of information between client and server is summarized in the above diagram.
1231
1232Note that the client-server pair can speak SOCK_STREAM, SOCK_DGRAM, or anything else (as long as they’re speaking the same thing). Some good examples of client-server pairs are telnet/telnetd, ftp/ftpd, or Firefox/Apache. Every time you use ftp, there’s a remote program, ftpd, that serves you.
1233
1234Often, there will only be one server on a machine, and that server will handle multiple clients using fork(). The basic routine is: server will wait for a connection, accept() it, and fork() a child process to handle it. This is what our sample server does in the next section.
1235
1236A Simple Stream Server
1237All this server does is send the string “Hello, world!” out over a stream connection. All you need to do to test this server is run it in one window, and telnet to it from another with:
1238
1239 $ telnet remotehostname 3490
1240where remotehostname is the name of the machine you’re running it on.
1241
1242The server code23:
1243
1244/*
1245** server.c -- a stream socket server demo
1246*/
1247
1248#include <stdio.h>
1249#include <stdlib.h>
1250#include <unistd.h>
1251#include <errno.h>
1252#include <string.h>
1253#include <sys/types.h>
1254#include <sys/socket.h>
1255#include <netinet/in.h>
1256#include <netdb.h>
1257#include <arpa/inet.h>
1258#include <sys/wait.h>
1259#include <signal.h>
1260
1261#define PORT "3490" // the port users will be connecting to
1262
1263#define BACKLOG 10 // how many pending connections queue will hold
1264
1265void sigchld_handler(int s)
1266{
1267 // waitpid() might overwrite errno, so we save and restore it:
1268 int saved_errno = errno;
1269
1270 while(waitpid(-1, NULL, WNOHANG) > 0);
1271
1272 errno = saved_errno;
1273}
1274
1275
1276// get sockaddr, IPv4 or IPv6:
1277void *get_in_addr(struct sockaddr *sa)
1278{
1279 if (sa->sa_family == AF_INET) {
1280 return &(((struct sockaddr_in*)sa)->sin_addr);
1281 }
1282
1283 return &(((struct sockaddr_in6*)sa)->sin6_addr);
1284}
1285
1286int main(void)
1287{
1288 int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
1289 struct addrinfo hints, *servinfo, *p;
1290 struct sockaddr_storage their_addr; // connector's address information
1291 socklen_t sin_size;
1292 struct sigaction sa;
1293 int yes=1;
1294 char s[INET6_ADDRSTRLEN];
1295 int rv;
1296
1297 memset(&hints, 0, sizeof hints);
1298 hints.ai_family = AF_UNSPEC;
1299 hints.ai_socktype = SOCK_STREAM;
1300 hints.ai_flags = AI_PASSIVE; // use my IP
1301
1302 if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
1303 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
1304 return 1;
1305 }
1306
1307 // loop through all the results and bind to the first we can
1308 for(p = servinfo; p != NULL; p = p->ai_next) {
1309 if ((sockfd = socket(p->ai_family, p->ai_socktype,
1310 p->ai_protocol)) == -1) {
1311 perror("server: socket");
1312 continue;
1313 }
1314
1315 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
1316 sizeof(int)) == -1) {
1317 perror("setsockopt");
1318 exit(1);
1319 }
1320
1321 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
1322 close(sockfd);
1323 perror("server: bind");
1324 continue;
1325 }
1326
1327 break;
1328 }
1329
1330 freeaddrinfo(servinfo); // all done with this structure
1331
1332 if (p == NULL) {
1333 fprintf(stderr, "server: failed to bind\n");
1334 exit(1);
1335 }
1336
1337 if (listen(sockfd, BACKLOG) == -1) {
1338 perror("listen");
1339 exit(1);
1340 }
1341
1342 sa.sa_handler = sigchld_handler; // reap all dead processes
1343 sigemptyset(&sa.sa_mask);
1344 sa.sa_flags = SA_RESTART;
1345 if (sigaction(SIGCHLD, &sa, NULL) == -1) {
1346 perror("sigaction");
1347 exit(1);
1348 }
1349
1350 printf("server: waiting for connections...\n");
1351
1352 while(1) { // main accept() loop
1353 sin_size = sizeof their_addr;
1354 new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
1355 if (new_fd == -1) {
1356 perror("accept");
1357 continue;
1358 }
1359
1360 inet_ntop(their_addr.ss_family,
1361 get_in_addr((struct sockaddr *)&their_addr),
1362 s, sizeof s);
1363 printf("server: got connection from %s\n", s);
1364
1365 if (!fork()) { // this is the child process
1366 close(sockfd); // child doesn't need the listener
1367 if (send(new_fd, "Hello, world!", 13, 0) == -1)
1368 perror("send");
1369 close(new_fd);
1370 exit(0);
1371 }
1372 close(new_fd); // parent doesn't need this
1373 }
1374
1375 return 0;
1376}
1377In case you’re curious, I have the code in one big main() function for (I feel) syntactic clarity. Feel free to split it into smaller functions if it makes you feel better.
1378
1379(Also, this whole sigaction() thing might be new to you—that’s ok. The code that’s there is responsible for reaping zombie processes that appear as the fork()ed child processes exit. If you make lots of zombies and don’t reap them, your system administrator will become agitated.)
1380
1381You can get the data from this server by using the client listed in the next section.
1382
1383A Simple Stream Client
1384This guy’s even easier than the server. All this client does is connect to the host you specify on the command line, port 3490. It gets the string that the server sends.
1385
1386The client source24:
1387
1388/*
1389** client.c -- a stream socket client demo
1390*/
1391
1392#include <stdio.h>
1393#include <stdlib.h>
1394#include <unistd.h>
1395#include <errno.h>
1396#include <string.h>
1397#include <netdb.h>
1398#include <sys/types.h>
1399#include <netinet/in.h>
1400#include <sys/socket.h>
1401
1402#include <arpa/inet.h>
1403
1404#define PORT "3490" // the port client will be connecting to
1405
1406#define MAXDATASIZE 100 // max number of bytes we can get at once
1407
1408// get sockaddr, IPv4 or IPv6:
1409void *get_in_addr(struct sockaddr *sa)
1410{
1411 if (sa->sa_family == AF_INET) {
1412 return &(((struct sockaddr_in*)sa)->sin_addr);
1413 }
1414
1415 return &(((struct sockaddr_in6*)sa)->sin6_addr);
1416}
1417
1418int main(int argc, char *argv[])
1419{
1420 int sockfd, numbytes;
1421 char buf[MAXDATASIZE];
1422 struct addrinfo hints, *servinfo, *p;
1423 int rv;
1424 char s[INET6_ADDRSTRLEN];
1425
1426 if (argc != 2) {
1427 fprintf(stderr,"usage: client hostname\n");
1428 exit(1);
1429 }
1430
1431 memset(&hints, 0, sizeof hints);
1432 hints.ai_family = AF_UNSPEC;
1433 hints.ai_socktype = SOCK_STREAM;
1434
1435 if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
1436 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
1437 return 1;
1438 }
1439
1440 // loop through all the results and connect to the first we can
1441 for(p = servinfo; p != NULL; p = p->ai_next) {
1442 if ((sockfd = socket(p->ai_family, p->ai_socktype,
1443 p->ai_protocol)) == -1) {
1444 perror("client: socket");
1445 continue;
1446 }
1447
1448 if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
1449 close(sockfd);
1450 perror("client: connect");
1451 continue;
1452 }
1453
1454 break;
1455 }
1456
1457 if (p == NULL) {
1458 fprintf(stderr, "client: failed to connect\n");
1459 return 2;
1460 }
1461
1462 inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
1463 s, sizeof s);
1464 printf("client: connecting to %s\n", s);
1465
1466 freeaddrinfo(servinfo); // all done with this structure
1467
1468 if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
1469 perror("recv");
1470 exit(1);
1471 }
1472
1473 buf[numbytes] = '\0';
1474
1475 printf("client: received '%s'\n",buf);
1476
1477 close(sockfd);
1478
1479 return 0;
1480}
1481Notice that if you don’t run the server before you run the client, connect() returns “Connection refused”. Very useful.
1482
1483Datagram Sockets
1484We’ve already covered the basics of UDP datagram sockets with our discussion of sendto() and recvfrom(), above, so I’ll just present a couple of sample programs: talker.c and listener.c.
1485
1486listener sits on a machine waiting for an incoming packet on port 4950. talker sends a packet to that port, on the specified machine, that contains whatever the user enters on the command line.
1487
1488Here is the source for listener.c25:
1489
1490/*
1491** listener.c -- a datagram sockets "server" demo
1492*/
1493
1494#include <stdio.h>
1495#include <stdlib.h>
1496#include <unistd.h>
1497#include <errno.h>
1498#include <string.h>
1499#include <sys/types.h>
1500#include <sys/socket.h>
1501#include <netinet/in.h>
1502#include <arpa/inet.h>
1503#include <netdb.h>
1504
1505#define MYPORT "4950" // the port users will be connecting to
1506
1507#define MAXBUFLEN 100
1508
1509// get sockaddr, IPv4 or IPv6:
1510void *get_in_addr(struct sockaddr *sa)
1511{
1512 if (sa->sa_family == AF_INET) {
1513 return &(((struct sockaddr_in*)sa)->sin_addr);
1514 }
1515
1516 return &(((struct sockaddr_in6*)sa)->sin6_addr);
1517}
1518
1519int main(void)
1520{
1521 int sockfd;
1522 struct addrinfo hints, *servinfo, *p;
1523 int rv;
1524 int numbytes;
1525 struct sockaddr_storage their_addr;
1526 char buf[MAXBUFLEN];
1527 socklen_t addr_len;
1528 char s[INET6_ADDRSTRLEN];
1529
1530 memset(&hints, 0, sizeof hints);
1531 hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
1532 hints.ai_socktype = SOCK_DGRAM;
1533 hints.ai_flags = AI_PASSIVE; // use my IP
1534
1535 if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
1536 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
1537 return 1;
1538 }
1539
1540 // loop through all the results and bind to the first we can
1541 for(p = servinfo; p != NULL; p = p->ai_next) {
1542 if ((sockfd = socket(p->ai_family, p->ai_socktype,
1543 p->ai_protocol)) == -1) {
1544 perror("listener: socket");
1545 continue;
1546 }
1547
1548 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
1549 close(sockfd);
1550 perror("listener: bind");
1551 continue;
1552 }
1553
1554 break;
1555 }
1556
1557 if (p == NULL) {
1558 fprintf(stderr, "listener: failed to bind socket\n");
1559 return 2;
1560 }
1561
1562 freeaddrinfo(servinfo);
1563
1564 printf("listener: waiting to recvfrom...\n");
1565
1566 addr_len = sizeof their_addr;
1567 if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
1568 (struct sockaddr *)&their_addr, &addr_len)) == -1) {
1569 perror("recvfrom");
1570 exit(1);
1571 }
1572
1573 printf("listener: got packet from %s\n",
1574 inet_ntop(their_addr.ss_family,
1575 get_in_addr((struct sockaddr *)&their_addr),
1576 s, sizeof s));
1577 printf("listener: packet is %d bytes long\n", numbytes);
1578 buf[numbytes] = '\0';
1579 printf("listener: packet contains \"%s\"\n", buf);
1580
1581 close(sockfd);
1582
1583 return 0;
1584}
1585Notice that in our call to getaddrinfo() we’re finally using SOCK_DGRAM. Also, note that there’s no need to listen() or accept(). This is one of the perks of using unconnected datagram sockets!
1586
1587Next comes the source for talker.c26:
1588
1589/*
1590** talker.c -- a datagram "client" demo
1591*/
1592
1593#include <stdio.h>
1594#include <stdlib.h>
1595#include <unistd.h>
1596#include <errno.h>
1597#include <string.h>
1598#include <sys/types.h>
1599#include <sys/socket.h>
1600#include <netinet/in.h>
1601#include <arpa/inet.h>
1602#include <netdb.h>
1603
1604#define SERVERPORT "4950" // the port users will be connecting to
1605
1606int main(int argc, char *argv[])
1607{
1608 int sockfd;
1609 struct addrinfo hints, *servinfo, *p;
1610 int rv;
1611 int numbytes;
1612
1613 if (argc != 3) {
1614 fprintf(stderr,"usage: talker hostname message\n");
1615 exit(1);
1616 }
1617
1618 memset(&hints, 0, sizeof hints);
1619 hints.ai_family = AF_UNSPEC;
1620 hints.ai_socktype = SOCK_DGRAM;
1621
1622 if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) {
1623 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
1624 return 1;
1625 }
1626
1627 // loop through all the results and make a socket
1628 for(p = servinfo; p != NULL; p = p->ai_next) {
1629 if ((sockfd = socket(p->ai_family, p->ai_socktype,
1630 p->ai_protocol)) == -1) {
1631 perror("talker: socket");
1632 continue;
1633 }
1634
1635 break;
1636 }
1637
1638 if (p == NULL) {
1639 fprintf(stderr, "talker: failed to create socket\n");
1640 return 2;
1641 }
1642
1643 if ((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0,
1644 p->ai_addr, p->ai_addrlen)) == -1) {
1645 perror("talker: sendto");
1646 exit(1);
1647 }
1648
1649 freeaddrinfo(servinfo);
1650
1651 printf("talker: sent %d bytes to %s\n", numbytes, argv[1]);
1652 close(sockfd);
1653
1654 return 0;
1655}
1656And that’s all there is to it! Run listener on some machine, then run talker on another. Watch them communicate! Fun G-rated excitement for the entire nuclear family!
1657
1658You don’t even have to run the server this time! You can run talker by itself, and it just happily fires packets off into the ether where they disappear if no one is ready with a recvfrom() on the other side. Remember: data sent using UDP datagram sockets isn’t guaranteed to arrive!
1659
1660Except for one more tiny detail that I’ve mentioned many times in the past: connected datagram sockets. I need to talk about this here, since we’re in the datagram section of the document. Let’s say that talker calls connect() and specifies the listener’s address. From that point on, talker may only sent to and receive from the address specified by connect(). For this reason, you don’t have to use sendto() and recvfrom(); you can simply use send() and recv().
1661
1662Slightly Advanced Techniques
1663These aren’t really advanced, but they’re getting out of the more basic levels we’ve already covered. In fact, if you’ve gotten this far, you should consider yourself fairly accomplished in the basics of Unix network programming! Congratulations!
1664
1665So here we go into the brave new world of some of the more esoteric things you might want to learn about sockets. Have at it!
1666
1667Blocking
1668Blocking. You’ve heard about it—now what the heck is it? In a nutshell, “block” is techie jargon for “sleep”. You probably noticed that when you run listener, above, it just sits there until a packet arrives. What happened is that it called recvfrom(), there was no data, and so recvfrom() is said to “block” (that is, sleep there) until some data arrives.
1669
1670Lots of functions block. accept() blocks. All the recv() functions block. The reason they can do this is because they’re allowed to. When you first create the socket descriptor with socket(), the kernel sets it to blocking. If you don’t want a socket to be blocking, you have to make a call to fcntl():
1671
1672#include <unistd.h>
1673#include <fcntl.h>
1674.
1675.
1676.
1677sockfd = socket(PF_INET, SOCK_STREAM, 0);
1678fcntl(sockfd, F_SETFL, O_NONBLOCK);
1679.
1680.
1681.
1682By setting a socket to non-blocking, you can effectively “poll” the socket for information. If you try to read from a non-blocking socket and there’s no data there, it’s not allowed to block—it will return -1 and errno will be set to EAGAIN or EWOULDBLOCK.
1683
1684(Wait—it can return EAGAIN or EWOULDBLOCK? Which do you check for? The specification doesn’t actually specify which your system will return, so for portability, check them both.)
1685
1686Generally speaking, however, this type of polling is a bad idea. If you put your program in a busy-wait looking for data on the socket, you’ll suck up CPU time like it was going out of style. A more elegant solution for checking to see if there’s data waiting to be read comes in the following section on poll().
1687
1688poll()—Synchronous I/O Multiplexing
1689What you really want to be able to do is somehow monitor a bunch of sockets at once and then handle the ones that have data ready. This way you don’t have to continously poll all those sockets to see which are ready to read.
1690
1691A word of warning: poll() is horribly slow when it comes to giant numbers of connections. In those circumstances, you’ll get better performance out of an event library such as libevent27 that attempts to use the fastest possible method availabile on your system.
1692
1693So how can you avoid polling? Not slightly ironically, you can avoid polling by using the poll() system call. In a nutshell, we’re going to ask the operating system to do all the dirty work for us, and just let us know when some data is ready to read on which sockets. In the meantime, our process can go to sleep, saving system resources.
1694
1695The general gameplan is to keep an array of struct pollfds with information about which socket descriptors we want to monitor, and what kind of events we want to monitor for. The OS will block on the poll() call until one of those events occurs (e.g. “socket ready to read!”) or until a user-specified timeout occurs.
1696
1697Usefully, a listen()ing socket will return “ready to read” when a new incoming connection is ready to be accept()ed.
1698
1699That’s enough banter. How do we use this?
1700
1701 #include <poll.h>
1702
1703 int poll(struct pollfd fds[], nfds_t nfds, int timeout);
1704fds is our array of information (which sockets to monitor for what), nfds is the count of elements in the array, and timeout is a timeout in milliseconds. It returns the number of elements in the array that have had an event occur.
1705
1706Let’s have a look at that struct:
1707
1708 struct pollfd {
1709 int fd; // the socket descriptor
1710 short events; // bitmap of events we're interested in
1711 short revents; // when poll() returns, bitmap of events that occurred
1712 };
1713So we’re going to have an array of those, and we’ll see the fd field for each element to a socket descriptor we’re interested in monitoring. And then we’ll set the events field to indicate the type of events we’re interested in.
1714
1715The events field is the bitwise-OR of the following:
1716
1717Macro Description
1718POLLIN Alert me when data is ready to recv() on this socket.
1719POLLOUT Alert me when I can send() data to this socket without blocking.
1720Once you have your array of struct pollfds in order, then you can pass it to poll(), also passing the size of the array, as well as a timeout value in milliseconds. (You can specify a negative timeout to wait forever.)
1721
1722After poll() returns, you can check the revents field to see if POLLIN or POLLOUT is set, indicating that event occurred.
1723
1724(There’s actually more that you can do with the poll() call. See the poll() man page, below, for more details.)
1725
1726Here’s an example28 where we’ll wait 2.5 seconds for data to be ready to read from standard input, i.e. when you hit RETURN:
1727
1728#include <stdio.h>
1729#include <poll.h>
1730
1731int main(void)
1732{
1733 struct pollfd pfds[1]; // More if you want to monitor more
1734
1735 pfds[0].fd = 0; // Standard input
1736 pfds[0].events = POLLIN; // Tell me when ready to read
1737
1738 // If you needed to monitor other things, as well:
1739 //pfds[1].fd = some_socket; // Some socket descriptor
1740 //pfds[1].events = POLLIN; // Tell me when ready to read
1741
1742 printf("Hit RETURN or wait 2.5 seconds for timeout\n");
1743
1744 int num_events = poll(pfds, 1, 2500); // 2.5 second timeout
1745
1746 if (num_events == 0) {
1747 printf("Poll timed out!\n");
1748 } else {
1749 int pollin_happened = pfds[0].revents & POLLIN;
1750
1751 if (pollin_happened) {
1752 printf("File descriptor %d is ready to read\n", pfds[0].fd);
1753 } else {
1754 printf("Unexpected event occurred: %d\n", pfds[0].revents);
1755 }
1756 }
1757
1758 return 0;
1759}
1760Notice again that poll() returns the number of elements in the pfds array for which events have occurred. It doesn’t tell you which elements in the array (you still have to scan for that), but it does tell you how many entries have a non-zero revents field (so you can stop scanning after you find that many).
1761
1762A couple questions might come up here: how to I add new file descriptors to the set I pass to poll()? For this, simply make sure you have enough space in the array for all you need, or realloc() more space as needed.
1763
1764What about deleting items from the set? For this, you can copy the last element in the array over-top the one you’re deleting. And then pass in one fewer as the count to poll(). Another option is that you can set any fd field to a negative number and poll() will ignore it.
1765
1766How can we put it all together into a chat server that you can telnet to?
1767
1768What we’ll do is start a listener socket, and add it to the set of file descriptors to poll(). (It will show ready-to-read when there’s an incoming connection.)
1769
1770Then we’ll add new connections to our struct pollfd array. And we’ll grow it dynamically if we run out of space.
1771
1772When a connection is closed, we’ll remove it from the array.
1773
1774And when a connection is ready-to-read, we’ll read the data from it and send that data to all the other connections so they can see what the other users typed.
1775
1776So give this poll server29 a try. Run it in one window, then telnet localhost 9034 from a number of other terminal windows. You should be able to see what you type in one window in the other ones (after you hit RETURN).
1777
1778Not only that, but if you hit CTRL-] and type quit to exit telnet, the server should detect the disconnection and remove you from the array of file descriptors.
1779
1780/*
1781** pollserver.c -- a cheezy multiperson chat server
1782*/
1783
1784#include <stdio.h>
1785#include <stdlib.h>
1786#include <string.h>
1787#include <unistd.h>
1788#include <sys/types.h>
1789#include <sys/socket.h>
1790#include <netinet/in.h>
1791#include <arpa/inet.h>
1792#include <netdb.h>
1793#include <poll.h>
1794
1795#define PORT "9034" // Port we're listening on
1796
1797// Get sockaddr, IPv4 or IPv6:
1798void *get_in_addr(struct sockaddr *sa)
1799{
1800 if (sa->sa_family == AF_INET) {
1801 return &(((struct sockaddr_in*)sa)->sin_addr);
1802 }
1803
1804 return &(((struct sockaddr_in6*)sa)->sin6_addr);
1805}
1806
1807// Return a listening socket
1808int get_listener_socket(void)
1809{
1810 int listener; // Listening socket descriptor
1811 int yes=1; // For setsockopt() SO_REUSEADDR, below
1812 int rv;
1813
1814 struct addrinfo hints, *ai, *p;
1815
1816 // Get us a socket and bind it
1817 memset(&hints, 0, sizeof hints);
1818 hints.ai_family = AF_UNSPEC;
1819 hints.ai_socktype = SOCK_STREAM;
1820 hints.ai_flags = AI_PASSIVE;
1821 if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
1822 fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
1823 exit(1);
1824 }
1825
1826 for(p = ai; p != NULL; p = p->ai_next) {
1827 listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
1828 if (listener < 0) {
1829 continue;
1830 }
1831
1832 // Lose the pesky "address already in use" error message
1833 setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
1834
1835 if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
1836 close(listener);
1837 continue;
1838 }
1839
1840 break;
1841 }
1842
1843 // If we got here, it means we didn't get bound
1844 if (p == NULL) {
1845 return -1;
1846 }
1847
1848 freeaddrinfo(ai); // All done with this
1849
1850 // Listen
1851 if (listen(listener, 10) == -1) {
1852 return -1;
1853 }
1854
1855 return listener;
1856}
1857
1858// Add a new file descriptor to the set
1859void add_to_pfds(struct pollfd *pfds[], int newfd, int *fd_count, int *fd_size)
1860{
1861 // If we don't have room, add more space in the pfds array
1862 if (*fd_count == *fd_size) {
1863 *fd_size *= 2; // Double it
1864
1865 *pfds = realloc(*pfds, sizeof(**pfds) * (*fd_size));
1866 }
1867
1868 (*pfds)[*fd_count].fd = newfd;
1869 (*pfds)[*fd_count].events = POLLIN; // Check ready-to-read
1870
1871 (*fd_count)++;
1872}
1873
1874// Remove an index from the set
1875void del_from_pfds(struct pollfd pfds[], int i, int *fd_count)
1876{
1877 // Copy the one from the end over this one
1878 pfds[i] = pfds[*fd_count-1];
1879
1880 (*fd_count)--;
1881}
1882
1883// Main
1884int main(void)
1885{
1886 int listener; // Listening socket descriptor
1887
1888 int newfd; // Newly accept()ed socket descriptor
1889 struct sockaddr_storage remoteaddr; // Client address
1890 socklen_t addrlen;
1891
1892 char buf[256]; // Buffer for client data
1893
1894 char remoteIP[INET6_ADDRSTRLEN];
1895
1896 // Start off with room for 5 connections
1897 // (We'll realloc as necessary)
1898 int fd_count = 0;
1899 int fd_size = 5;
1900 struct pollfd *pfds = malloc(sizeof *pfds * fd_size);
1901
1902 // Set up and get a listening socket
1903 listener = get_listener_socket();
1904
1905 if (listener == -1) {
1906 fprintf(stderr, "error getting listening socket\n");
1907 exit(1);
1908 }
1909
1910 // Add the listener to set
1911 pfds[0].fd = listener;
1912 pfds[0].events = POLLIN; // Report ready to read on incoming connection
1913
1914 fd_count = 1; // For the listener
1915
1916 // Main loop
1917 for(;;) {
1918 int poll_count = poll(pfds, fd_count, -1);
1919
1920 if (poll_count == -1) {
1921 perror("poll");
1922 exit(1);
1923 }
1924
1925 // Run through the existing connections looking for data to read
1926 for(int i = 0; i < fd_count; i++) {
1927
1928 // Check if someone's ready to read
1929 if (pfds[i].revents & POLLIN) { // We got one!!
1930
1931 if (pfds[i].fd == listener) {
1932 // If listener is ready to read, handle new connection
1933
1934 addrlen = sizeof remoteaddr;
1935 newfd = accept(listener,
1936 (struct sockaddr *)&remoteaddr,
1937 &addrlen);
1938
1939 if (newfd == -1) {
1940 perror("accept");
1941 } else {
1942 add_to_pfds(&pfds, newfd, &fd_count, &fd_size);
1943
1944 printf("pollserver: new connection from %s on "
1945 "socket %d\n",
1946 inet_ntop(remoteaddr.ss_family,
1947 get_in_addr((struct sockaddr*)&remoteaddr),
1948 remoteIP, INET6_ADDRSTRLEN),
1949 newfd);
1950 }
1951 } else {
1952 // If not the listener, we're just a regular client
1953 int nbytes = recv(pfds[i].fd, buf, sizeof buf, 0);
1954
1955 int sender_fd = pfds[i].fd;
1956
1957 if (nbytes <= 0) {
1958 // Got error or connection closed by client
1959 if (nbytes == 0) {
1960 // Connection closed
1961 printf("pollserver: socket %d hung up\n", sender_fd);
1962 } else {
1963 perror("recv");
1964 }
1965
1966 close(pfds[i].fd); // Bye!
1967
1968 del_from_pfds(pfds, i, &fd_count);
1969
1970 } else {
1971 // We got some good data from a client
1972
1973 for(int j = 0; j < fd_count; j++) {
1974 // Send to everyone!
1975 int dest_fd = pfds[j].fd;
1976
1977 // Except the listener and ourselves
1978 if (dest_fd != listener && dest_fd != sender_fd) {
1979 if (send(dest_fd, buf, nbytes, 0) == -1) {
1980 perror("send");
1981 }
1982 }
1983 }
1984 }
1985 } // END handle data from client
1986 } // END got ready-to-read from poll()
1987 } // END looping through file descriptors
1988 } // END for(;;)--and you thought it would never end!
1989
1990 return 0;
1991}
1992In the next section, we’ll look at a similar, older function called select(). Both select() and poll() offer similar functionality and performance, and only really differ in how they’re used. select() might be slightly more portable, but is perhaps a little clunkier in use. Choose the one you like the best, as long as it’s supported on your system.
1993
1994select()—Synchronous I/O Multiplexing, Old School
1995This function is somewhat strange, but it’s very useful. Take the following situation: you are a server and you want to listen for incoming connections as well as keep reading from the connections you already have.
1996
1997No problem, you say, just an accept() and a couple of recv()s. Not so fast, buster! What if you’re blocking on an accept() call? How are you going to recv() data at the same time? “Use non-blocking sockets!” No way! You don’t want to be a CPU hog. What, then?
1998
1999select() gives you the power to monitor several sockets at the same time. It’ll tell you which ones are ready for reading, which are ready for writing, and which sockets have raised exceptions, if you really want to know that.
2000
2001A word of warning: select(), though very portable, is terribly slow when it comes to giant numbers of connections. In those circumstances, you’ll get better performance out of an event library such as libevent30 that attempts to use the fastest possible method availabile on your system.
2002
2003Without any further ado, I’ll offer the synopsis of select():
2004
2005 #include <sys/time.h>
2006 #include <sys/types.h>
2007 #include <unistd.h>
2008
2009 int select(int numfds, fd_set *readfds, fd_set *writefds,
2010 fd_set *exceptfds, struct timeval *timeout);
2011The function monitors “sets” of file descriptors; in particular readfds, writefds, and exceptfds. If you want to see if you can read from standard input and some socket descriptor, sockfd, just add the file descriptors 0 and sockfd to the set readfds. The parameter numfds should be set to the values of the highest file descriptor plus one. In this example, it should be set to sockfd+1, since it is assuredly higher than standard input (0).
2012
2013When select() returns, readfds will be modified to reflect which of the file descriptors you selected which is ready for reading. You can test them with the macro FD_ISSET(), below.
2014
2015Before progressing much further, I’ll talk about how to manipulate these sets. Each set is of the type fd_set. The following macros operate on this type:
2016
2017Function Description
2018FD_SET(int fd, fd_set *set); Add fd to the set.
2019FD_CLR(int fd, fd_set *set); Remove fd from the set.
2020FD_ISSET(int fd, fd_set *set); Return true if fd is in the set.
2021FD_ZERO(fd_set *set); Clear all entries from the set.
2022Finally, what is this weirded out struct timeval? Well, sometimes you don’t want to wait forever for someone to send you some data. Maybe every 96 seconds you want to print “Still Going…” to the terminal even though nothing has happened. This time structure allows you to specify a timeout period. If the time is exceeded and select() still hasn’t found any ready file descriptors, it’ll return so you can continue processing.
2023
2024The struct timeval has the follow fields:
2025
2026 struct timeval {
2027 int tv_sec; // seconds
2028 int tv_usec; // microseconds
2029 };
2030Just set tv_sec to the number of seconds to wait, and set tv_usec to the number of microseconds to wait. Yes, that’s _micro_seconds, not milliseconds. There are 1,000 microseconds in a millisecond, and 1,000 milliseconds in a second. Thus, there are 1,000,000 microseconds in a second. Why is it “usec”? The “u” is supposed to look like the Greek letter μ (Mu) that we use for “micro”. Also, when the function returns, timeout might be updated to show the time still remaining. This depends on what flavor of Unix you’re running.
2031
2032Yay! We have a microsecond resolution timer! Well, don’t count on it. You’ll probably have to wait some part of your standard Unix timeslice no matter how small you set your struct timeval.
2033
2034Other things of interest: If you set the fields in your struct timeval to 0, select() will timeout immediately, effectively polling all the file descriptors in your sets. If you set the parameter timeout to NULL, it will never timeout, and will wait until the first file descriptor is ready. Finally, if you don’t care about waiting for a certain set, you can just set it to NULL in the call to select().
2035
2036The following code snippet31 waits 2.5 seconds for something to appear on standard input:
2037
2038/*
2039** select.c -- a select() demo
2040*/
2041
2042#include <stdio.h>
2043#include <sys/time.h>
2044#include <sys/types.h>
2045#include <unistd.h>
2046
2047#define STDIN 0 // file descriptor for standard input
2048
2049int main(void)
2050{
2051 struct timeval tv;
2052 fd_set readfds;
2053
2054 tv.tv_sec = 2;
2055 tv.tv_usec = 500000;
2056
2057 FD_ZERO(&readfds);
2058 FD_SET(STDIN, &readfds);
2059
2060 // don't care about writefds and exceptfds:
2061 select(STDIN+1, &readfds, NULL, NULL, &tv);
2062
2063 if (FD_ISSET(STDIN, &readfds))
2064 printf("A key was pressed!\n");
2065 else
2066 printf("Timed out.\n");
2067
2068 return 0;
2069}
2070If you’re on a line buffered terminal, the key you hit should be RETURN or it will time out anyway.
2071
2072Now, some of you might think this is a great way to wait for data on a datagram socket—and you are right: it might be. Some Unices can use select in this manner, and some can’t. You should see what your local man page says on the matter if you want to attempt it.
2073
2074Some Unices update the time in your struct timeval to reflect the amount of time still remaining before a timeout. But others do not. Don’t rely on that occurring if you want to be portable. (Use gettimeofday() if you need to track time elapsed. It’s a bummer, I know, but that’s the way it is.)
2075
2076What happens if a socket in the read set closes the connection? Well, in that case, select() returns with that socket descriptor set as “ready to read”. When you actually do recv() from it, recv() will return 0. That’s how you know the client has closed the connection.
2077
2078One more note of interest about select(): if you have a socket that is listen()ing, you can check to see if there is a new connection by putting that socket’s file descriptor in the readfds set.
2079
2080And that, my friends, is a quick overview of the almighty select() function.
2081
2082But, by popular demand, here is an in-depth example. Unfortunately, the difference between the dirt-simple example, above, and this one here is significant. But have a look, then read the description that follows it.
2083
2084This program32 acts like a simple multi-user chat server. Start it running in one window, then telnet to it (“telnet hostname 9034”) from multiple other windows. When you type something in one telnet session, it should appear in all the others.
2085
2086/*
2087** selectserver.c -- a cheezy multiperson chat server
2088*/
2089
2090#include <stdio.h>
2091#include <stdlib.h>
2092#include <string.h>
2093#include <unistd.h>
2094#include <sys/types.h>
2095#include <sys/socket.h>
2096#include <netinet/in.h>
2097#include <arpa/inet.h>
2098#include <netdb.h>
2099
2100#define PORT "9034" // port we're listening on
2101
2102// get sockaddr, IPv4 or IPv6:
2103void *get_in_addr(struct sockaddr *sa)
2104{
2105 if (sa->sa_family == AF_INET) {
2106 return &(((struct sockaddr_in*)sa)->sin_addr);
2107 }
2108
2109 return &(((struct sockaddr_in6*)sa)->sin6_addr);
2110}
2111
2112int main(void)
2113{
2114 fd_set master; // master file descriptor list
2115 fd_set read_fds; // temp file descriptor list for select()
2116 int fdmax; // maximum file descriptor number
2117
2118 int listener; // listening socket descriptor
2119 int newfd; // newly accept()ed socket descriptor
2120 struct sockaddr_storage remoteaddr; // client address
2121 socklen_t addrlen;
2122
2123 char buf[256]; // buffer for client data
2124 int nbytes;
2125
2126 char remoteIP[INET6_ADDRSTRLEN];
2127
2128 int yes=1; // for setsockopt() SO_REUSEADDR, below
2129 int i, j, rv;
2130
2131 struct addrinfo hints, *ai, *p;
2132
2133 FD_ZERO(&master); // clear the master and temp sets
2134 FD_ZERO(&read_fds);
2135
2136 // get us a socket and bind it
2137 memset(&hints, 0, sizeof hints);
2138 hints.ai_family = AF_UNSPEC;
2139 hints.ai_socktype = SOCK_STREAM;
2140 hints.ai_flags = AI_PASSIVE;
2141 if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
2142 fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
2143 exit(1);
2144 }
2145
2146 for(p = ai; p != NULL; p = p->ai_next) {
2147 listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
2148 if (listener < 0) {
2149 continue;
2150 }
2151
2152 // lose the pesky "address already in use" error message
2153 setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
2154
2155 if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
2156 close(listener);
2157 continue;
2158 }
2159
2160 break;
2161 }
2162
2163 // if we got here, it means we didn't get bound
2164 if (p == NULL) {
2165 fprintf(stderr, "selectserver: failed to bind\n");
2166 exit(2);
2167 }
2168
2169 freeaddrinfo(ai); // all done with this
2170
2171 // listen
2172 if (listen(listener, 10) == -1) {
2173 perror("listen");
2174 exit(3);
2175 }
2176
2177 // add the listener to the master set
2178 FD_SET(listener, &master);
2179
2180 // keep track of the biggest file descriptor
2181 fdmax = listener; // so far, it's this one
2182
2183 // main loop
2184 for(;;) {
2185 read_fds = master; // copy it
2186 if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
2187 perror("select");
2188 exit(4);
2189 }
2190
2191 // run through the existing connections looking for data to read
2192 for(i = 0; i <= fdmax; i++) {
2193 if (FD_ISSET(i, &read_fds)) { // we got one!!
2194 if (i == listener) {
2195 // handle new connections
2196 addrlen = sizeof remoteaddr;
2197 newfd = accept(listener,
2198 (struct sockaddr *)&remoteaddr,
2199 &addrlen);
2200
2201 if (newfd == -1) {
2202 perror("accept");
2203 } else {
2204 FD_SET(newfd, &master); // add to master set
2205 if (newfd > fdmax) { // keep track of the max
2206 fdmax = newfd;
2207 }
2208 printf("selectserver: new connection from %s on "
2209 "socket %d\n",
2210 inet_ntop(remoteaddr.ss_family,
2211 get_in_addr((struct sockaddr*)&remoteaddr),
2212 remoteIP, INET6_ADDRSTRLEN),
2213 newfd);
2214 }
2215 } else {
2216 // handle data from a client
2217 if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
2218 // got error or connection closed by client
2219 if (nbytes == 0) {
2220 // connection closed
2221 printf("selectserver: socket %d hung up\n", i);
2222 } else {
2223 perror("recv");
2224 }
2225 close(i); // bye!
2226 FD_CLR(i, &master); // remove from master set
2227 } else {
2228 // we got some data from a client
2229 for(j = 0; j <= fdmax; j++) {
2230 // send to everyone!
2231 if (FD_ISSET(j, &master)) {
2232 // except the listener and ourselves
2233 if (j != listener && j != i) {
2234 if (send(j, buf, nbytes, 0) == -1) {
2235 perror("send");
2236 }
2237 }
2238 }
2239 }
2240 }
2241 } // END handle data from client
2242 } // END got new incoming connection
2243 } // END looping through file descriptors
2244 } // END for(;;)--and you thought it would never end!
2245
2246 return 0;
2247}
2248Notice I have two file descriptor sets in the code: master and read_fds. The first, master, holds all the socket descriptors that are currently connected, as well as the socket descriptor that is listening for new connections.
2249
2250The reason I have the master set is that select() actually changes the set you pass into it to reflect which sockets are ready to read. Since I have to keep track of the connections from one call of select() to the next, I must store these safely away somewhere. At the last minute, I copy the master into the read_fds, and then call select().
2251
2252But doesn’t this mean that every time I get a new connection, I have to add it to the master set? Yup! And every time a connection closes, I have to remove it from the master set? Yes, it does.
2253
2254Notice I check to see when the listener socket is ready to read. When it is, it means I have a new connection pending, and I accept() it and add it to the master set. Similarly, when a client connection is ready to read, and recv() returns 0, I know the client has closed the connection, and I must remove it from the master set.
2255
2256If the client recv() returns non-zero, though, I know some data has been received. So I get it, and then go through the master list and send that data to all the rest of the connected clients.
2257
2258And that, my friends, is a less-than-simple overview of the almighty select() function.
2259
2260Quick note to all you Linux fans out there: sometimes, in rare circumstances, Linux’s select() can return “ready-to-read” and then not actually be ready to read! This means it will block on the read() after the select() says it won’t! Why you little—! Anyway, the workaround solution is to set the O_NONBLOCK flag on the receiving socket so it errors with EWOULDBLOCK (which you can just safely ignore if it occurs). See the fcntl() reference page for more info on setting a socket to non-blocking.
2261
2262In addition, here is a bonus afterthought: there is another function called poll() which behaves much the same way select() does, but with a different system for managing the file descriptor sets. Check it out!
2263
2264Handling Partial send()s
2265Remember back in the section about send(), above, when I said that send() might not send all the bytes you asked it to? That is, you want it to send 512 bytes, but it returns 412. What happened to the remaining 100 bytes?
2266
2267Well, they’re still in your little buffer waiting to be sent out. Due to circumstances beyond your control, the kernel decided not to send all the data out in one chunk, and now, my friend, it’s up to you to get the data out there.
2268
2269You could write a function like this to do it, too:
2270
2271#include <sys/types.h>
2272#include <sys/socket.h>
2273
2274int sendall(int s, char *buf, int *len)
2275{
2276 int total = 0; // how many bytes we've sent
2277 int bytesleft = *len; // how many we have left to send
2278 int n;
2279
2280 while(total < *len) {
2281 n = send(s, buf+total, bytesleft, 0);
2282 if (n == -1) { break; }
2283 total += n;
2284 bytesleft -= n;
2285 }
2286
2287 *len = total; // return number actually sent here
2288
2289 return n==-1?-1:0; // return -1 on failure, 0 on success
2290}
2291In this example, s is the socket you want to send the data to, buf is the buffer containing the data, and len is a pointer to an int containing the number of bytes in the buffer.
2292
2293The function returns -1 on error (and errno is still set from the call to send()). Also, the number of bytes actually sent is returned in len. This will be the same number of bytes you asked it to send, unless there was an error. sendall() will do it’s best, huffing and puffing, to send the data out, but if there’s an error, it gets back to you right away.
2294
2295For completeness, here’s a sample call to the function:
2296
2297char buf[10] = "Beej!";
2298int len;
2299
2300len = strlen(buf);
2301if (sendall(s, buf, &len) == -1) {
2302 perror("sendall");
2303 printf("We only sent %d bytes because of the error!\n", len);
2304}
2305What happens on the receiver’s end when part of a packet arrives? If the packets are variable length, how does the receiver know when one packet ends and another begins? Yes, real-world scenarios are a royal pain in the donkeys. You probably have to encapsulate (remember that from the data encapsulation section way back there at the beginning?) Read on for details!
2306
2307Serialization—How to Pack Data
2308It’s easy enough to send text data across the network, you’re finding, but what happens if you want to send some “binary” data like ints or floats? It turns out you have a few options.
2309
2310Convert the number into text with a function like sprintf(), then send the text. The receiver will parse the text back into a number using a function like strtol().
2311
2312Just send the data raw, passing a pointer to the data to send().
2313
2314Encode the number into a portable binary form. The receiver will decode it.
2315
2316Sneak preview! Tonight only!
2317
2318[Curtain raises]
2319
2320Beej says, “I prefer Method Three, above!”
2321
2322[THE END]
2323
2324(Before I begin this section in earnest, I should tell you that there are libraries out there for doing this, and rolling your own and remaining portable and error-free is quite a challenge. So hunt around and do your homework before deciding to implement this stuff yourself. I include the information here for those curious about how things like this work.)
2325
2326Actually all the methods, above, have their drawbacks and advantages, but, like I said, in general, I prefer the third method. First, though, let’s talk about some of the drawbacks and advantages to the other two.
2327
2328The first method, encoding the numbers as text before sending, has the advantage that you can easily print and read the data that’s coming over the wire. Sometimes a human-readable protocol is excellent to use in a non-bandwidth-intensive situation, such as with Internet Relay Chat (IRC)33. However, it has the disadvantage that it is slow to convert, and the results almost always take up more space than the original number!
2329
2330Method two: passing the raw data. This one is quite easy (but dangerous!): just take a pointer to the data to send, and call send with it.
2331
2332 double d = 3490.15926535;
2333
2334 send(s, &d, sizeof d, 0); /* DANGER--non-portable! */
2335The receiver gets it like this:
2336
2337 double d;
2338
2339 recv(s, &d, sizeof d, 0); /* DANGER--non-portable! */
2340Fast, simple—what’s not to like? Well, it turns out that not all architectures represent a double (or int for that matter) with the same bit representation or even the same byte ordering! The code is decidedly non-portable. (Hey—maybe you don’t need portability, in which case this is nice and fast.)
2341
2342When packing integer types, we’ve already seen how the htons()-class of functions can help keep things portable by transforming the numbers into Network Byte Order, and how that’s the Right Thing to do. Unfortunately, there are no similar functions for float types. Is all hope lost?
2343
2344Fear not! (Were you afraid there for a second? No? Not even a little bit?) There is something we can do: we can pack (or “marshal”, or “serialize”, or one of a thousand million other names) the data into a known binary format that the receiver can unpack on the remote side.
2345
2346What do I mean by “known binary format”? Well, we’ve already seen the htons() example, right? It changes (or “encodes”, if you want to think of it that way) a number from whatever the host format is into Network Byte Order. To reverse (unencode) the number, the receiver calls ntohs().
2347
2348But didn’t I just get finished saying there wasn’t any such function for other non-integer types? Yes. I did. And since there’s no standard way in C to do this, it’s a bit of a pickle (that a gratuitous pun there for you Python fans).
2349
2350The thing to do is to pack the data into a known format and send that over the wire for decoding. For example, to pack floats, here’s something quick and dirty with plenty of room for improvement34:
2351
2352#include <stdint.h>
2353
2354uint32_t htonf(float f)
2355{
2356 uint32_t p;
2357 uint32_t sign;
2358
2359 if (f < 0) { sign = 1; f = -f; }
2360 else { sign = 0; }
2361
2362 p = ((((uint32_t)f)&0x7fff)<<16) | (sign<<31); // whole part and sign
2363 p |= (uint32_t)(((f - (int)f) * 65536.0f))&0xffff; // fraction
2364
2365 return p;
2366}
2367
2368float ntohf(uint32_t p)
2369{
2370 float f = ((p>>16)&0x7fff); // whole part
2371 f += (p&0xffff) / 65536.0f; // fraction
2372
2373 if (((p>>31)&0x1) == 0x1) { f = -f; } // sign bit set
2374
2375 return f;
2376}
2377The above code is sort of a naive implementation that stores a float in a 32-bit number. The high bit (31) is used to store the sign of the number (“1” means negative), and the next seven bits (30-16) are used to store the whole number portion of the float. Finally, the remaining bits (15-0) are used to store the fractional portion of the number.
2378
2379Usage is fairly straightforward:
2380
2381#include <stdio.h>
2382
2383int main(void)
2384{
2385 float f = 3.1415926, f2;
2386 uint32_t netf;
2387
2388 netf = htonf(f); // convert to "network" form
2389 f2 = ntohf(netf); // convert back to test
2390
2391 printf("Original: %f\n", f); // 3.141593
2392 printf(" Network: 0x%08X\n", netf); // 0x0003243F
2393 printf("Unpacked: %f\n", f2); // 3.141586
2394
2395 return 0;
2396}
2397On the plus side, it’s small, simple, and fast. On the minus side, it’s not an efficient use of space and the range is severely restricted—try storing a number greater-than 32767 in there and it won’t be very happy! You can also see in the above example that the last couple decimal places are not correctly preserved.
2398
2399What can we do instead? Well, The Standard for storing floating point numbers is known as IEEE-75435. Most computers use this format internally for doing floating point math, so in those cases, strictly speaking, conversion wouldn’t need to be done. But if you want your source code to be portable, that’s an assumption you can’t necessarily make. (On the other hand, if you want things to be fast, you should optimize this out on platforms that don’t need to do it! That’s what htons() and its ilk do.)
2400
2401Here’s some code that encodes floats and doubles into IEEE-754 format36. (Mostly—it doesn’t encode NaN or Infinity, but it could be modified to do that.)
2402
2403#define pack754_32(f) (pack754((f), 32, 8))
2404#define pack754_64(f) (pack754((f), 64, 11))
2405#define unpack754_32(i) (unpack754((i), 32, 8))
2406#define unpack754_64(i) (unpack754((i), 64, 11))
2407
2408uint64_t pack754(long double f, unsigned bits, unsigned expbits)
2409{
2410 long double fnorm;
2411 int shift;
2412 long long sign, exp, significand;
2413 unsigned significandbits = bits - expbits - 1; // -1 for sign bit
2414
2415 if (f == 0.0) return 0; // get this special case out of the way
2416
2417 // check sign and begin normalization
2418 if (f < 0) { sign = 1; fnorm = -f; }
2419 else { sign = 0; fnorm = f; }
2420
2421 // get the normalized form of f and track the exponent
2422 shift = 0;
2423 while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }
2424 while(fnorm < 1.0) { fnorm *= 2.0; shift--; }
2425 fnorm = fnorm - 1.0;
2426
2427 // calculate the binary form (non-float) of the significand data
2428 significand = fnorm * ((1LL<<significandbits) + 0.5f);
2429
2430 // get the biased exponent
2431 exp = shift + ((1<<(expbits-1)) - 1); // shift + bias
2432
2433 // return the final answer
2434 return (sign<<(bits-1)) | (exp<<(bits-expbits-1)) | significand;
2435}
2436
2437long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
2438{
2439 long double result;
2440 long long shift;
2441 unsigned bias;
2442 unsigned significandbits = bits - expbits - 1; // -1 for sign bit
2443
2444 if (i == 0) return 0.0;
2445
2446 // pull the significand
2447 result = (i&((1LL<<significandbits)-1)); // mask
2448 result /= (1LL<<significandbits); // convert back to float
2449 result += 1.0f; // add the one back on
2450
2451 // deal with the exponent
2452 bias = (1<<(expbits-1)) - 1;
2453 shift = ((i>>significandbits)&((1LL<<expbits)-1)) - bias;
2454 while(shift > 0) { result *= 2.0; shift--; }
2455 while(shift < 0) { result /= 2.0; shift++; }
2456
2457 // sign it
2458 result *= (i>>(bits-1))&1? -1.0: 1.0;
2459
2460 return result;
2461}
2462I put some handy macros up there at the top for packing and unpacking 32-bit (probably a float) and 64-bit (probably a double) numbers, but the pack754() function could be called directly and told to encode bits-worth of data (expbits of which are reserved for the normalized number’s exponent).
2463
2464Here’s sample usage:
2465
2466
2467#include <stdio.h>
2468#include <stdint.h> // defines uintN_t types
2469#include <inttypes.h> // defines PRIx macros
2470
2471int main(void)
2472{
2473 float f = 3.1415926, f2;
2474 double d = 3.14159265358979323, d2;
2475 uint32_t fi;
2476 uint64_t di;
2477
2478 fi = pack754_32(f);
2479 f2 = unpack754_32(fi);
2480
2481 di = pack754_64(d);
2482 d2 = unpack754_64(di);
2483
2484 printf("float before : %.7f\n", f);
2485 printf("float encoded: 0x%08" PRIx32 "\n", fi);
2486 printf("float after : %.7f\n\n", f2);
2487
2488 printf("double before : %.20lf\n", d);
2489 printf("double encoded: 0x%016" PRIx64 "\n", di);
2490 printf("double after : %.20lf\n", d2);
2491
2492 return 0;
2493}
2494The above code produces this output:
2495
2496 float before : 3.1415925
2497 float encoded: 0x40490FDA
2498 float after : 3.1415925
2499
2500 double before : 3.14159265358979311600
2501 double encoded: 0x400921FB54442D18
2502 double after : 3.14159265358979311600
2503Another question you might have is how do you pack structs? Unfortunately for you, the compiler is free to put padding all over the place in a struct, and that means you can’t portably send the whole thing over the wire in one chunk. (Aren’t you getting sick of hearing “can’t do this”, “can’t do that”? Sorry! To quote a friend, “Whenever anything goes wrong, I always blame Microsoft.” This one might not be Microsoft’s fault, admittedly, but my friend’s statement is completely true.)
2504
2505Back to it: the best way to send the struct over the wire is to pack each field independently and then unpack them into the struct when they arrive on the other side.
2506
2507That’s a lot of work, is what you’re thinking. Yes, it is. One thing you can do is write a helper function to help pack the data for you. It’ll be fun! Really!
2508
2509In the book The Practice of Programming37 by Kernighan and Pike, they implement printf()-like functions called pack() and unpack() that do exactly this. I’d link to them, but apparently those functions aren’t online with the rest of the source from the book.
2510
2511(The Practice of Programming is an excellent read. Zeus saves a kitten every time I recommend it.)
2512
2513At this point, I’m going to drop a pointer to a Protocol Buffers implementation in C38 which I’ve never used, but looks completely respectable. Python and Perl programmers will want to check out their language’s pack() and unpack() functions for accomplishing the same thing. And Java has a big-ol’ Serializable interface that can be used in a similar way.
2514
2515But if you want to write your own packing utility in C, K&P’s trick is to use variable argument lists to make printf()-like functions to build the packets. Here’s a version I cooked up39 on my own based on that which hopefully will be enough to give you an idea of how such a thing can work.
2516
2517(This code references the pack754() functions, above. The packi*() functions operate like the familiar htons() family, except they pack into a char array instead of another integer.)
2518
2519#include <stdio.h>
2520#include <ctype.h>
2521#include <stdarg.h>
2522#include <string.h>
2523
2524/*
2525** packi16() -- store a 16-bit int into a char buffer (like htons())
2526*/
2527void packi16(unsigned char *buf, unsigned int i)
2528{
2529 *buf++ = i>>8; *buf++ = i;
2530}
2531
2532/*
2533** packi32() -- store a 32-bit int into a char buffer (like htonl())
2534*/
2535void packi32(unsigned char *buf, unsigned long int i)
2536{
2537 *buf++ = i>>24; *buf++ = i>>16;
2538 *buf++ = i>>8; *buf++ = i;
2539}
2540
2541/*
2542** packi64() -- store a 64-bit int into a char buffer (like htonl())
2543*/
2544void packi64(unsigned char *buf, unsigned long long int i)
2545{
2546 *buf++ = i>>56; *buf++ = i>>48;
2547 *buf++ = i>>40; *buf++ = i>>32;
2548 *buf++ = i>>24; *buf++ = i>>16;
2549 *buf++ = i>>8; *buf++ = i;
2550}
2551
2552/*
2553** unpacki16() -- unpack a 16-bit int from a char buffer (like ntohs())
2554*/
2555int unpacki16(unsigned char *buf)
2556{
2557 unsigned int i2 = ((unsigned int)buf[0]<<8) | buf[1];
2558 int i;
2559
2560 // change unsigned numbers to signed
2561 if (i2 <= 0x7fffu) { i = i2; }
2562 else { i = -1 - (unsigned int)(0xffffu - i2); }
2563
2564 return i;
2565}
2566
2567/*
2568** unpacku16() -- unpack a 16-bit unsigned from a char buffer (like ntohs())
2569*/
2570unsigned int unpacku16(unsigned char *buf)
2571{
2572 return ((unsigned int)buf[0]<<8) | buf[1];
2573}
2574
2575/*
2576** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl())
2577*/
2578long int unpacki32(unsigned char *buf)
2579{
2580 unsigned long int i2 = ((unsigned long int)buf[0]<<24) |
2581 ((unsigned long int)buf[1]<<16) |
2582 ((unsigned long int)buf[2]<<8) |
2583 buf[3];
2584 long int i;
2585
2586 // change unsigned numbers to signed
2587 if (i2 <= 0x7fffffffu) { i = i2; }
2588 else { i = -1 - (long int)(0xffffffffu - i2); }
2589
2590 return i;
2591}
2592
2593/*
2594** unpacku32() -- unpack a 32-bit unsigned from a char buffer (like ntohl())
2595*/
2596unsigned long int unpacku32(unsigned char *buf)
2597{
2598 return ((unsigned long int)buf[0]<<24) |
2599 ((unsigned long int)buf[1]<<16) |
2600 ((unsigned long int)buf[2]<<8) |
2601 buf[3];
2602}
2603
2604/*
2605** unpacki64() -- unpack a 64-bit int from a char buffer (like ntohl())
2606*/
2607long long int unpacki64(unsigned char *buf)
2608{
2609 unsigned long long int i2 = ((unsigned long long int)buf[0]<<56) |
2610 ((unsigned long long int)buf[1]<<48) |
2611 ((unsigned long long int)buf[2]<<40) |
2612 ((unsigned long long int)buf[3]<<32) |
2613 ((unsigned long long int)buf[4]<<24) |
2614 ((unsigned long long int)buf[5]<<16) |
2615 ((unsigned long long int)buf[6]<<8) |
2616 buf[7];
2617 long long int i;
2618
2619 // change unsigned numbers to signed
2620 if (i2 <= 0x7fffffffffffffffu) { i = i2; }
2621 else { i = -1 -(long long int)(0xffffffffffffffffu - i2); }
2622
2623 return i;
2624}
2625
2626/*
2627** unpacku64() -- unpack a 64-bit unsigned from a char buffer (like ntohl())
2628*/
2629unsigned long long int unpacku64(unsigned char *buf)
2630{
2631 return ((unsigned long long int)buf[0]<<56) |
2632 ((unsigned long long int)buf[1]<<48) |
2633 ((unsigned long long int)buf[2]<<40) |
2634 ((unsigned long long int)buf[3]<<32) |
2635 ((unsigned long long int)buf[4]<<24) |
2636 ((unsigned long long int)buf[5]<<16) |
2637 ((unsigned long long int)buf[6]<<8) |
2638 buf[7];
2639}
2640
2641/*
2642** pack() -- store data dictated by the format string in the buffer
2643**
2644** bits |signed unsigned float string
2645** -----+----------------------------------
2646** 8 | c C
2647** 16 | h H f
2648** 32 | l L d
2649** 64 | q Q g
2650** - | s
2651**
2652** (16-bit unsigned length is automatically prepended to strings)
2653*/
2654
2655unsigned int pack(unsigned char *buf, char *format, ...)
2656{
2657 va_list ap;
2658
2659 signed char c; // 8-bit
2660 unsigned char C;
2661
2662 int h; // 16-bit
2663 unsigned int H;
2664
2665 long int l; // 32-bit
2666 unsigned long int L;
2667
2668 long long int q; // 64-bit
2669 unsigned long long int Q;
2670
2671 float f; // floats
2672 double d;
2673 long double g;
2674 unsigned long long int fhold;
2675
2676 char *s; // strings
2677 unsigned int len;
2678
2679 unsigned int size = 0;
2680
2681 va_start(ap, format);
2682
2683 for(; *format != '\0'; format++) {
2684 switch(*format) {
2685 case 'c': // 8-bit
2686 size += 1;
2687 c = (signed char)va_arg(ap, int); // promoted
2688 *buf++ = c;
2689 break;
2690
2691 case 'C': // 8-bit unsigned
2692 size += 1;
2693 C = (unsigned char)va_arg(ap, unsigned int); // promoted
2694 *buf++ = C;
2695 break;
2696
2697 case 'h': // 16-bit
2698 size += 2;
2699 h = va_arg(ap, int);
2700 packi16(buf, h);
2701 buf += 2;
2702 break;
2703
2704 case 'H': // 16-bit unsigned
2705 size += 2;
2706 H = va_arg(ap, unsigned int);
2707 packi16(buf, H);
2708 buf += 2;
2709 break;
2710
2711 case 'l': // 32-bit
2712 size += 4;
2713 l = va_arg(ap, long int);
2714 packi32(buf, l);
2715 buf += 4;
2716 break;
2717
2718 case 'L': // 32-bit unsigned
2719 size += 4;
2720 L = va_arg(ap, unsigned long int);
2721 packi32(buf, L);
2722 buf += 4;
2723 break;
2724
2725 case 'q': // 64-bit
2726 size += 8;
2727 q = va_arg(ap, long long int);
2728 packi64(buf, q);
2729 buf += 8;
2730 break;
2731
2732 case 'Q': // 64-bit unsigned
2733 size += 8;
2734 Q = va_arg(ap, unsigned long long int);
2735 packi64(buf, Q);
2736 buf += 8;
2737 break;
2738
2739 case 'f': // float-16
2740 size += 2;
2741 f = (float)va_arg(ap, double); // promoted
2742 fhold = pack754_16(f); // convert to IEEE 754
2743 packi16(buf, fhold);
2744 buf += 2;
2745 break;
2746
2747 case 'd': // float-32
2748 size += 4;
2749 d = va_arg(ap, double);
2750 fhold = pack754_32(d); // convert to IEEE 754
2751 packi32(buf, fhold);
2752 buf += 4;
2753 break;
2754
2755 case 'g': // float-64
2756 size += 8;
2757 g = va_arg(ap, long double);
2758 fhold = pack754_64(g); // convert to IEEE 754
2759 packi64(buf, fhold);
2760 buf += 8;
2761 break;
2762
2763 case 's': // string
2764 s = va_arg(ap, char*);
2765 len = strlen(s);
2766 size += len + 2;
2767 packi16(buf, len);
2768 buf += 2;
2769 memcpy(buf, s, len);
2770 buf += len;
2771 break;
2772 }
2773 }
2774
2775 va_end(ap);
2776
2777 return size;
2778}
2779
2780/*
2781** unpack() -- unpack data dictated by the format string into the buffer
2782**
2783** bits |signed unsigned float string
2784** -----+----------------------------------
2785** 8 | c C
2786** 16 | h H f
2787** 32 | l L d
2788** 64 | q Q g
2789** - | s
2790**
2791** (string is extracted based on its stored length, but 's' can be
2792** prepended with a max length)
2793*/
2794void unpack(unsigned char *buf, char *format, ...)
2795{
2796 va_list ap;
2797
2798 signed char *c; // 8-bit
2799 unsigned char *C;
2800
2801 int *h; // 16-bit
2802 unsigned int *H;
2803
2804 long int *l; // 32-bit
2805 unsigned long int *L;
2806
2807 long long int *q; // 64-bit
2808 unsigned long long int *Q;
2809
2810 float *f; // floats
2811 double *d;
2812 long double *g;
2813 unsigned long long int fhold;
2814
2815 char *s;
2816 unsigned int len, maxstrlen=0, count;
2817
2818 va_start(ap, format);
2819
2820 for(; *format != '\0'; format++) {
2821 switch(*format) {
2822 case 'c': // 8-bit
2823 c = va_arg(ap, signed char*);
2824 if (*buf <= 0x7f) { *c = *buf;} // re-sign
2825 else { *c = -1 - (unsigned char)(0xffu - *buf); }
2826 buf++;
2827 break;
2828
2829 case 'C': // 8-bit unsigned
2830 C = va_arg(ap, unsigned char*);
2831 *C = *buf++;
2832 break;
2833
2834 case 'h': // 16-bit
2835 h = va_arg(ap, int*);
2836 *h = unpacki16(buf);
2837 buf += 2;
2838 break;
2839
2840 case 'H': // 16-bit unsigned
2841 H = va_arg(ap, unsigned int*);
2842 *H = unpacku16(buf);
2843 buf += 2;
2844 break;
2845
2846 case 'l': // 32-bit
2847 l = va_arg(ap, long int*);
2848 *l = unpacki32(buf);
2849 buf += 4;
2850 break;
2851
2852 case 'L': // 32-bit unsigned
2853 L = va_arg(ap, unsigned long int*);
2854 *L = unpacku32(buf);
2855 buf += 4;
2856 break;
2857
2858 case 'q': // 64-bit
2859 q = va_arg(ap, long long int*);
2860 *q = unpacki64(buf);
2861 buf += 8;
2862 break;
2863
2864 case 'Q': // 64-bit unsigned
2865 Q = va_arg(ap, unsigned long long int*);
2866 *Q = unpacku64(buf);
2867 buf += 8;
2868 break;
2869
2870 case 'f': // float
2871 f = va_arg(ap, float*);
2872 fhold = unpacku16(buf);
2873 *f = unpack754_16(fhold);
2874 buf += 2;
2875 break;
2876
2877 case 'd': // float-32
2878 d = va_arg(ap, double*);
2879 fhold = unpacku32(buf);
2880 *d = unpack754_32(fhold);
2881 buf += 4;
2882 break;
2883
2884 case 'g': // float-64
2885 g = va_arg(ap, long double*);
2886 fhold = unpacku64(buf);
2887 *g = unpack754_64(fhold);
2888 buf += 8;
2889 break;
2890
2891 case 's': // string
2892 s = va_arg(ap, char*);
2893 len = unpacku16(buf);
2894 buf += 2;
2895 if (maxstrlen > 0 && len >= maxstrlen) count = maxstrlen - 1;
2896 else count = len;
2897 memcpy(s, buf, count);
2898 s[count] = '\0';
2899 buf += len;
2900 break;
2901
2902 default:
2903 if (isdigit(*format)) { // track max str len
2904 maxstrlen = maxstrlen * 10 + (*format-'0');
2905 }
2906 }
2907
2908 if (!isdigit(*format)) maxstrlen = 0;
2909 }
2910
2911 va_end(ap);
2912}
2913And here is a demonstration program40 of the above code that packs some data into buf and then unpacks it into variables. Note that when calling unpack() with a string argument (format specifier “s”), it’s wise to put a maximum length count in front of it to prevent a buffer overrun, e.g. “96s”. Be wary when unpacking data you get over the network—a malicious user might send badly-constructed packets in an effort to attack your system!
2914
2915#include <stdio.h>
2916
2917// various bits for floating point types--
2918// varies for different architectures
2919typedef float float32_t;
2920typedef double float64_t;
2921
2922int main(void)
2923{
2924 unsigned char buf[1024];
2925 int8_t magic;
2926 int16_t monkeycount;
2927 int32_t altitude;
2928 float32_t absurdityfactor;
2929 char *s = "Great unmitigated Zot! You've found the Runestaff!";
2930 char s2[96];
2931 int16_t packetsize, ps2;
2932
2933 packetsize = pack(buf, "chhlsf", (int8_t)'B', (int16_t)0, (int16_t)37,
2934 (int32_t)-5, s, (float32_t)-3490.6677);
2935 packi16(buf+1, packetsize); // store packet size in packet for kicks
2936
2937 printf("packet is %" PRId32 " bytes\n", packetsize);
2938
2939 unpack(buf, "chhl96sf", &magic, &ps2, &monkeycount, &altitude, s2,
2940 &absurdityfactor);
2941
2942 printf("'%c' %" PRId32" %" PRId16 " %" PRId32
2943 " \"%s\" %f\n", magic, ps2, monkeycount,
2944 altitude, s2, absurdityfactor);
2945
2946 return 0;
2947}
2948Whether you roll your own code or use someone else’s, it’s a good idea to have a general set of data packing routines for the sake of keeping bugs in check, rather than packing each bit by hand each time.
2949
2950When packing the data, what’s a good format to use? Excellent question. Fortunately, RFC 450641, the External Data Representation Standard, already defines binary formats for a bunch of different types, like floating point types, integer types, arrays, raw data, etc. I suggest conforming to that if you’re going to roll the data yourself. But you’re not obligated to. The Packet Police are not right outside your door. At least, I don’t think they are.
2951
2952In any case, encoding the data somehow or another before you send it is the right way of doing things!
2953
2954Son of Data Encapsulation
2955What does it really mean to encapsulate data, anyway? In the simplest case, it means you’ll stick a header on there with either some identifying information or a packet length, or both.
2956
2957What should your header look like? Well, it’s just some binary data that represents whatever you feel is necessary to complete your project.
2958
2959Wow. That’s vague.
2960
2961Okay. For instance, let’s say you have a multi-user chat program that uses SOCK_STREAMs. When a user types (“says”) something, two pieces of information need to be transmitted to the server: what was said and who said it.
2962
2963So far so good? “What’s the problem?” you’re asking.
2964
2965The problem is that the messages can be of varying lengths. One person named “tom” might say, “Hi”, and another person named “Benjamin” might say, “Hey guys what is up?”
2966
2967So you send() all this stuff to the clients as it comes in. Your outgoing data stream looks like this:
2968
2969 t o m H i B e n j a m i n H e y g u y s w h a t i s u p ?
2970And so on. How does the client know when one message starts and another stops? You could, if you wanted, make all messages the same length and just call the sendall() we implemented, above. But that wastes bandwidth! We don’t want to send() 1024 bytes just so “tom” can say “Hi”.
2971
2972So we encapsulate the data in a tiny header and packet structure. Both the client and server know how to pack and unpack (sometimes referred to as “marshal” and “unmarshal”) this data. Don’t look now, but we’re starting to define a protocol that describes how a client and server communicate!
2973
2974In this case, let’s assume the user name is a fixed length of 8 characters, padded with '\0'. And then let’s assume the data is variable length, up to a maximum of 128 characters. Let’s have a look a sample packet structure that we might use in this situation:
2975
2976len (1 byte, unsigned)—The total length of the packet, counting the 8-byte user name and chat data.
2977
2978name (8 bytes)—The user’s name, NUL-padded if necessary.
2979
2980chatdata (n-bytes)—The data itself, no more than 128 bytes. The length of the packet should be calculated as the length of this data plus 8 (the length of the name field, above).
2981
2982Why did I choose the 8-byte and 128-byte limits for the fields? I pulled them out of the air, assuming they’d be long enough. Maybe, though, 8 bytes is too restrictive for your needs, and you can have a 30-byte name field, or whatever. The choice is up to you.
2983
2984Using the above packet definition, the first packet would consist of the following information (in hex and ASCII):
2985
2986 0A 74 6F 6D 00 00 00 00 00 48 69
2987 (length) T o m (padding) H i
2988And the second is similar:
2989
2990 18 42 65 6E 6A 61 6D 69 6E 48 65 79 20 67 75 79 73 20 77 ...
2991 (length) B e n j a m i n H e y g u y s w ...
2992(The length is stored in Network Byte Order, of course. In this case, it’s only one byte so it doesn’t matter, but generally speaking you’ll want all your binary integers to be stored in Network Byte Order in your packets.)
2993
2994When you’re sending this data, you should be safe and use a command similar to sendall(), above, so you know all the data is sent, even if it takes multiple calls to send() to get it all out.
2995
2996Likewise, when you’re receiving this data, you need to do a bit of extra work. To be safe, you should assume that you might receive a partial packet (like maybe we receive “18 42 65 6E 6A” from Benjamin, above, but that’s all we get in this call to recv()). We need to call recv() over and over again until the packet is completely received.
2997
2998But how? Well, we know the number of bytes we need to receive in total for the packet to be complete, since that number is tacked on the front of the packet. We also know the maximum packet size is 1+8+128, or 137 bytes (because that’s how we defined the packet).
2999
3000There are actually a couple things you can do here. Since you know every packet starts off with a length, you can call recv() just to get the packet length. Then once you have that, you can call it again specifying exactly the remaining length of the packet (possibly repeatedly to get all the data) until you have the complete packet. The advantage of this method is that you only need a buffer large enough for one packet, while the disadvantage is that you need to call recv() at least twice to get all the data.
3001
3002Another option is just to call recv() and say the amount you’re willing to receive is the maximum number of bytes in a packet. Then whatever you get, stick it onto the back of a buffer, and finally check to see if the packet is complete. Of course, you might get some of the next packet, so you’ll need to have room for that.
3003
3004What you can do is declare an array big enough for two packets. This is your work array where you will reconstruct packets as they arrive.
3005
3006Every time you recv() data, you’ll append it into the work buffer and check to see if the packet is complete. That is, the number of bytes in the buffer is greater than or equal to the length specified in the header (+1, because the length in the header doesn’t include the byte for the length itself). If the number of bytes in the buffer is less than 1, the packet is not complete, obviously. You have to make a special case for this, though, since the first byte is garbage and you can’t rely on it for the correct packet length.
3007
3008Once the packet is complete, you can do with it what you will. Use it, and remove it from your work buffer.
3009
3010Whew! Are you juggling that in your head yet? Well, here’s the second of the one-two punch: you might have read past the end of one packet and onto the next in a single recv() call. That is, you have a work buffer with one complete packet, and an incomplete part of the next packet! Bloody heck. (But this is why you made your work buffer large enough to hold two packets—in case this happened!)
3011
3012Since you know the length of the first packet from the header, and you’ve been keeping track of the number of bytes in the work buffer, you can subtract and calculate how many of the bytes in the work buffer belong to the second (incomplete) packet. When you’ve handled the first one, you can clear it out of the work buffer and move the partial second packet down the to front of the buffer so it’s all ready to go for the next recv().
3013
3014(Some of you readers will note that actually moving the partial second packet to the beginning of the work buffer takes time, and the program can be coded to not require this by using a circular buffer. Unfortunately for the rest of you, a discussion on circular buffers is beyond the scope of this article. If you’re still curious, grab a data structures book and go from there.)
3015
3016I never said it was easy. Ok, I did say it was easy. And it is; you just need practice and pretty soon it’ll come to you naturally. By Excalibur I swear it!
3017
3018Broadcast Packets—Hello, World!
3019So far, this guide has talked about sending data from one host to one other host. But it is possible, I insist, that you can, with the proper authority, send data to multiple hosts at the same time!
3020
3021With UDP (only UDP, not TCP) and standard IPv4, this is done through a mechanism called broadcasting. With IPv6, broadcasting isn’t supported, and you have to resort to the often superior technique of multicasting, which, sadly I won’t be discussing at this time. But enough of the starry-eyed future—we’re stuck in the 32-bit present.
3022
3023But wait! You can’t just run off and start broadcasting willy-nilly; You have to set the socket option SO_BROADCAST before you can send a broadcast packet out on the network. It’s like a one of those little plastic covers they put over the missile launch switch! That’s just how much power you hold in your hands!
3024
3025But seriously, though, there is a danger to using broadcast packets, and that is: every system that receives a broadcast packet must undo all the onion-skin layers of data encapsulation until it finds out what port the data is destined to. And then it hands the data over or discards it. In either case, it’s a lot of work for each machine that receives the broadcast packet, and since it is all of them on the local network, that could be a lot of machines doing a lot of unnecessary work. When the game Doom first came out, this was a complaint about its network code.
3026
3027Now, there is more than one way to skin a cat… wait a minute. Is there really more than one way to skin a cat? What kind of expression is that? Uh, and likewise, there is more than one way to send a broadcast packet. So, to get to the meat and potatoes of the whole thing: how do you specify the destination address for a broadcast message? There are two common ways:
3028
3029Send the data to a specific subnet’s broadcast address. This is the subnet’s network number with all one-bits set for the host portion of the address. For instance, at home my network is 192.168.1.0, my netmask is 255.255.255.0, so the last byte of the address is my host number (because the first three bytes, according to the netmask, are the network number). So my broadcast address is 192.168.1.255. Under Unix, the ifconfig command will actually give you all this data. (If you’re curious, the bitwise logic to get your broadcast address is network_number OR (NOT netmask).) You can send this type of broadcast packet to remote networks as well as your local network, but you run the risk of the packet being dropped by the destination’s router. (If they didn’t drop it, then some random smurf could start flooding their LAN with broadcast traffic.)
3030
3031Send the data to the “global” broadcast address. This is 255.255.255.255, aka INADDR_BROADCAST. Many machines will automatically bitwise AND this with your network number to convert it to a network broadcast address, but some won’t. It varies. Routers do not forward this type of broadcast packet off your local network, ironically enough.
3032
3033So what happens if you try to send data on the broadcast address without first setting the SO_BROADCAST socket option? Well, let’s fire up good old talker and listener and see what happens.
3034
3035 $ talker 192.168.1.2 foo
3036 sent 3 bytes to 192.168.1.2
3037 $ talker 192.168.1.255 foo
3038 sendto: Permission denied
3039 $ talker 255.255.255.255 foo
3040 sendto: Permission denied
3041Yes, it’s not happy at all…because we didn’t set the SO_BROADCAST socket option. Do that, and now you can sendto() anywhere you want!
3042
3043In fact, that’s the only difference between a UDP application that can broadcast and one that can’t. So let’s take the old talker application and add one section that sets the SO_BROADCAST socket option. We’ll call this program broadcaster.c42:
3044
3045/*
3046** broadcaster.c -- a datagram "client" like talker.c, except
3047** this one can broadcast
3048*/
3049
3050#include <stdio.h>
3051#include <stdlib.h>
3052#include <unistd.h>
3053#include <errno.h>
3054#include <string.h>
3055#include <sys/types.h>
3056#include <sys/socket.h>
3057#include <netinet/in.h>
3058#include <arpa/inet.h>
3059#include <netdb.h>
3060
3061#define SERVERPORT 4950 // the port users will be connecting to
3062
3063int main(int argc, char *argv[])
3064{
3065 int sockfd;
3066 struct sockaddr_in their_addr; // connector's address information
3067 struct hostent *he;
3068 int numbytes;
3069 int broadcast = 1;
3070 //char broadcast = '1'; // if that doesn't work, try this
3071
3072 if (argc != 3) {
3073 fprintf(stderr,"usage: broadcaster hostname message\n");
3074 exit(1);
3075 }
3076
3077 if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
3078 perror("gethostbyname");
3079 exit(1);
3080 }
3081
3082 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
3083 perror("socket");
3084 exit(1);
3085 }
3086
3087 // this call is what allows broadcast packets to be sent:
3088 if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
3089 sizeof broadcast) == -1) {
3090 perror("setsockopt (SO_BROADCAST)");
3091 exit(1);
3092 }
3093
3094 their_addr.sin_family = AF_INET; // host byte order
3095 their_addr.sin_port = htons(SERVERPORT); // short, network byte order
3096 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
3097 memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
3098
3099 if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
3100 (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) {
3101 perror("sendto");
3102 exit(1);
3103 }
3104
3105 printf("sent %d bytes to %s\n", numbytes,
3106 inet_ntoa(their_addr.sin_addr));
3107
3108 close(sockfd);
3109
3110 return 0;
3111}
3112What’s different between this and a “normal” UDP client/server situation? Nothing! (With the exception of the client being allowed to send broadcast packets in this case.) As such, go ahead and run the old UDP listener program in one window, and broadcaster in another. You should be now be able to do all those sends that failed, above.
3113
3114 $ broadcaster 192.168.1.2 foo
3115 sent 3 bytes to 192.168.1.2
3116 $ broadcaster 192.168.1.255 foo
3117 sent 3 bytes to 192.168.1.255
3118 $ broadcaster 255.255.255.255 foo
3119 sent 3 bytes to 255.255.255.255
3120And you should see listener responding that it got the packets. (If listener doesn’t respond, it could be because it’s bound to an IPv6 address. Try changing the AF_UNSPEC in listener.c to AF_INET to force IPv4.)
3121
3122Well, that’s kind of exciting. But now fire up listener on another machine next to you on the same network so that you have two copies going, one on each machine, and run broadcaster again with your broadcast address… Hey! Both listeners get the packet even though you only called sendto() once! Cool!
3123
3124If the listener gets data you send directly to it, but not data on the broadcast address, it could be that you have a firewall on your local machine that is blocking the packets. (Yes, Pat and Bapper, thank you for realizing before I did that this is why my sample code wasn’t working. I told you I’d mention you in the guide, and here you are. So nyah.)
3125
3126Again, be careful with broadcast packets. Since every machine on the LAN will be forced to deal with the packet whether it recvfrom()s it or not, it can present quite a load to the entire computing network. They are definitely to be used sparingly and appropriately.
3127
3128Common Questions
3129Where can I get those header files?
3130
3131If you don’t have them on your system already, you probably don’t need them. Check the manual for your particular platform. If you’re building for Windows, you only need to #include <winsock.h>.
3132
3133What do I do when bind() reports “Address already in use”?
3134
3135You have to use setsockopt() with the SO_REUSEADDR option on the listening socket. Check out the section on bind() and the section on select() for an example.
3136
3137How do I get a list of open sockets on the system?
3138
3139Use the netstat. Check the man page for full details, but you should get some good output just typing:
3140
3141 $ netstat
3142The only trick is determining which socket is associated with which program. :-)
3143
3144How can I view the routing table?
3145
3146Run the route command (in /sbin on most Linuxes) or the command netstat -r.
3147
3148How can I run the client and server programs if I only have one computer? Don’t I need a network to write network programs?
3149
3150Fortunately for you, virtually all machines implement a loopback network “device” that sits in the kernel and pretends to be a network card. (This is the interface listed as “lo” in the routing table.)
3151
3152Pretend you’re logged into a machine named “goat”. Run the client in one window and the server in another. Or start the server in the background (“server &”) and run the client in the same window. The upshot of the loopback device is that you can either client goat or client localhost (since “localhost” is likely defined in your /etc/hosts file) and you’ll have the client talking to the server without a network!
3153
3154In short, no changes are necessary to any of the code to make it run on a single non-networked machine! Huzzah!
3155
3156How can I tell if the remote side has closed connection?
3157
3158You can tell because recv() will return 0.
3159
3160How do I implement a “ping” utility? What is ICMP? Where can I find out more about raw sockets and SOCK_RAW?
3161
3162All your raw sockets questions will be answered in W. Richard Stevens’ UNIX Network Programming books. Also, look in the ping/ subdirectory in Stevens’ UNIX Network Programming source code, available online43.
3163
3164How do I change or shorten the timeout on a call to connect()?
3165
3166Instead of giving you exactly the same answer that W. Richard Stevens would give you, I’ll just refer you to lib/connect_nonb.c in the UNIX Network Programming source code44.
3167
3168The gist of it is that you make a socket descriptor with socket(), set it to non-blocking, call connect(), and if all goes well connect() will return -1 immediately and errno will be set to EINPROGRESS. Then you call select() with whatever timeout you want, passing the socket descriptor in both the read and write sets. If it doesn’t timeout, it means the connect() call completed. At this point, you’ll have to use getsockopt() with the SO_ERROR option to get the return value from the connect() call, which should be zero if there was no error.
3169
3170Finally, you’ll probably want to set the socket back to be blocking again before you start transferring data over it.
3171
3172Notice that this has the added benefit of allowing your program to do something else while it’s connecting, too. You could, for example, set the timeout to something low, like 500 ms, and update an indicator onscreen each timeout, then call select() again. When you’ve called select() and timed-out, say, 20 times, you’ll know it’s time to give up on the connection.
3173
3174Like I said, check out Stevens’ source for a perfectly excellent example.
3175
3176How do I build for Windows?
3177
3178First, delete Windows and install Linux or BSD. };-). No, actually, just see the section on building for Windows in the introduction.
3179
3180How do I build for Solaris/SunOS? I keep getting linker errors when I try to compile!
3181
3182The linker errors happen because Sun boxes don’t automatically compile in the socket libraries. See the section on building for Solaris/SunOS in the introduction for an example of how to do this.
3183
3184Why does select() keep falling out on a signal?
3185
3186Signals tend to cause blocked system calls to return -1 with errno set to EINTR. When you set up a signal handler with sigaction(), you can set the flag SA_RESTART, which is supposed to restart the system call after it was interrupted.
3187
3188Naturally, this doesn’t always work.
3189
3190My favorite solution to this involves a goto statement. You know this irritates your professors to no end, so go for it!
3191
3192select_restart:
3193if ((err = select(fdmax+1, &readfds, NULL, NULL, NULL)) == -1) {
3194 if (errno == EINTR) {
3195 // some signal just interrupted us, so restart
3196 goto select_restart;
3197 }
3198 // handle the real error here:
3199 perror("select");
3200}
3201Sure, you don’t need to use goto in this case; you can use other structures to control it. But I think the goto statement is actually cleaner.
3202
3203How can I implement a timeout on a call to recv()?
3204
3205Use select()! It allows you to specify a timeout parameter for socket descriptors that you’re looking to read from. Or, you could wrap the entire functionality in a single function, like this:
3206
3207#include <unistd.h>
3208#include <sys/time.h>
3209#include <sys/types.h>
3210#include <sys/socket.h>
3211
3212int recvtimeout(int s, char *buf, int len, int timeout)
3213{
3214 fd_set fds;
3215 int n;
3216 struct timeval tv;
3217
3218 // set up the file descriptor set
3219 FD_ZERO(&fds);
3220 FD_SET(s, &fds);
3221
3222 // set up the struct timeval for the timeout
3223 tv.tv_sec = timeout;
3224 tv.tv_usec = 0;
3225
3226 // wait until timeout or data received
3227 n = select(s+1, &fds, NULL, NULL, &tv);
3228 if (n == 0) return -2; // timeout!
3229 if (n == -1) return -1; // error
3230
3231 // data must be here, so do a normal recv()
3232 return recv(s, buf, len, 0);
3233}
3234.
3235.
3236.
3237// Sample call to recvtimeout():
3238n = recvtimeout(s, buf, sizeof buf, 10); // 10 second timeout
3239
3240if (n == -1) {
3241 // error occurred
3242 perror("recvtimeout");
3243}
3244else if (n == -2) {
3245 // timeout occurred
3246} else {
3247 // got some data in buf
3248}
3249.
3250.
3251.
3252Notice that recvtimeout() returns -2 in case of a timeout. Why not return 0? Well, if you recall, a return value of 0 on a call to recv() means that the remote side closed the connection. So that return value is already spoken for, and -1 means “error”, so I chose -2 as my timeout indicator.
3253
3254How do I encrypt or compress the data before sending it through the socket?
3255
3256One easy way to do encryption is to use SSL (secure sockets layer), but that’s beyond the scope of this guide. (Check out the OpenSSL project45 for more info.)
3257
3258But assuming you want to plug in or implement your own compressor or encryption system, it’s just a matter of thinking of your data as running through a sequence of steps between both ends. Each step changes the data in some way.
3259
3260server reads data from file (or wherever)
3261server encrypts/compresses data (you add this part)
3262server send()s encrypted data
3263Now the other way around:
3264
3265client recv()s encrypted data
3266client decrypts/decompresses data (you add this part)
3267client writes data to file (or wherever)
3268If you’re going to compress and encrypt, just remember to compress first. :-)
3269
3270Just as long as the client properly undoes what the server does, the data will be fine in the end no matter how many intermediate steps you add.
3271
3272So all you need to do to use my code is to find the place between where the data is read and the data is sent (using send()) over the network, and stick some code in there that does the encryption.
3273
3274What is this “PF_INET” I keep seeing? Is it related to AF_INET?
3275
3276Yes, yes it is. See the section on socket() for details.
3277
3278How can I write a server that accepts shell commands from a client and executes them?
3279
3280For simplicity, lets say the client connect()s, send()s, and close()s the connection (that is, there are no subsequent system calls without the client connecting again).
3281
3282The process the client follows is this:
3283
3284connect() to server
3285send("/sbin/ls > /tmp/client.out")
3286close() the connection
3287Meanwhile, the server is handling the data and executing it:
3288
3289accept() the connection from the client
3290recv(str) the command string
3291close() the connection
3292system(str) to run the command
3293Beware! Having the server execute what the client says is like giving remote shell access and people can do things to your account when they connect to the server. For instance, in the above example, what if the client sends “rm -rf ~”? It deletes everything in your account, that’s what!
3294
3295So you get wise, and you prevent the client from using any except for a couple utilities that you know are safe, like the foobar utility:
3296
3297 if (!strncmp(str, "foobar", 6)) {
3298 sprintf(sysstr, "%s > /tmp/server.out", str);
3299 system(sysstr);
3300 }
3301But you’re still unsafe, unfortunately: what if the client enters “foobar; rm -rf ~”? The safest thing to do is to write a little routine that puts an escape (“\”) character in front of all non-alphanumeric characters (including spaces, if appropriate) in the arguments for the command.
3302
3303As you can see, security is a pretty big issue when the server starts executing things the client sends.
3304
3305I’m sending a slew of data, but when I recv(), it only receives 536 bytes or 1460 bytes at a time. But if I run it on my local machine, it receives all the data at the same time. What’s going on?
3306
3307You’re hitting the MTU—the maximum size the physical medium can handle. On the local machine, you’re using the loopback device which can handle 8K or more no problem. But on Ethernet, which can only handle 1500 bytes with a header, you hit that limit. Over a modem, with 576 MTU (again, with header), you hit the even lower limit.
3308
3309You have to make sure all the data is being sent, first of all. (See the sendall() function implementation for details.) Once you’re sure of that, then you need to call recv() in a loop until all your data is read.
3310
3311Read the section Son of Data Encapsulation for details on receiving complete packets of data using multiple calls to recv().
3312
3313I’m on a Windows box and I don’t have the fork() system call or any kind of struct sigaction. What to do?
3314
3315If they’re anywhere, they’ll be in POSIX libraries that may have shipped with your compiler. Since I don’t have a Windows box, I really can’t tell you the answer, but I seem to remember that Microsoft has a POSIX compatibility layer and that’s where fork() would be. (And maybe even sigaction.)
3316
3317Search the help that came with VC++ for “fork” or “POSIX” and see if it gives you any clues.
3318
3319If that doesn’t work at all, ditch the fork()/sigaction stuff and replace it with the Win32 equivalent: CreateProcess(). I don’t know how to use CreateProcess()—it takes a bazillion arguments, but it should be covered in the docs that came with VC++.
3320
3321I’m behind a firewall—how do I let people outside the firewall know my IP address so they can connect to my machine?
3322
3323Unfortunately, the purpose of a firewall is to prevent people outside the firewall from connecting to machines inside the firewall, so allowing them to do so is basically considered a breach of security.
3324
3325This isn’t to say that all is lost. For one thing, you can still often connect() through the firewall if it’s doing some kind of masquerading or NAT or something like that. Just design your programs so that you’re always the one initiating the connection, and you’ll be fine.
3326
3327If that’s not satisfactory, you can ask your sysadmins to poke a hole in the firewall so that people can connect to you. The firewall can forward to you either through it’s NAT software, or through a proxy or something like that.
3328
3329Be aware that a hole in the firewall is nothing to be taken lightly. You have to make sure you don’t give bad people access to the internal network; if you’re a beginner, it’s a lot harder to make software secure than you might imagine.
3330
3331Don’t make your sysadmin mad at me. ;-)
3332
3333How do I write a packet sniffer? How do I put my Ethernet interface into promiscuous mode?
3334
3335For those not in the know, when a network card is in “promiscuous mode”, it will forward ALL packets to the operating system, not just those that were addressed to this particular machine. (We’re talking Ethernet-layer addresses here, not IP addresses–but since ethernet is lower-layer than IP, all IP addresses are effectively forwarded as well. See the section Low Level Nonsense and Network Theory for more info.)
3336
3337This is the basis for how a packet sniffer works. It puts the interface into promiscuous mode, then the OS gets every single packet that goes by on the wire. You’ll have a socket of some type that you can read this data from.
3338
3339Unfortunately, the answer to the question varies depending on the platform, but if you Google for, for instance, “windows promiscuous ioctl” you’ll probably get somewhere. For Linux, there’s what looks like a useful Stack Overflow thread46, as well.
3340
3341How can I set a custom timeout value for a TCP or UDP socket?
3342
3343It depends on your system. You might search the net for SO_RCVTIMEO and SO_SNDTIMEO (for use with setsockopt()) to see if your system supports such functionality.
3344
3345The Linux man page suggests using alarm() or setitimer() as a substitute.
3346
3347How can I tell which ports are available to use? Is there a list of “official” port numbers?
3348
3349Usually this isn’t an issue. If you’re writing, say, a web server, then it’s a good idea to use the well-known port 80 for your software. If you’re writing just your own specialized server, then choose a port at random (but greater than 1023) and give it a try.
3350
3351If the port is already in use, you’ll get an “Address already in use” error when you try to bind(). Choose another port. (It’s a good idea to allow the user of your software to specify an alternate port either with a config file or a command line switch.)
3352
3353There is a list of official port numbers47 maintained by the Internet Assigned Numbers Authority (IANA). Just because something (over 1023) is in that list doesn’t mean you can’t use the port. For instance, Id Software’s DOOM uses the same port as “mdqs”, whatever that is. All that matters is that no one else on the same machine is using that port when you want to use it.
3354
3355Man Pages
3356In the Unix world, there are a lot of manuals. They have little sections that describe individual functions that you have at your disposal.
3357
3358Of course, manual would be too much of a thing to type. I mean, no one in the Unix world, including myself, likes to type that much. Indeed I could go on and on at great length about how much I prefer to be terse but instead I shall be brief and not bore you with long-winded diatribes about how utterly amazingly brief I prefer to be in virtually all circumstances in their entirety.
3359
3360[Applause]
3361
3362Thank you. What I am getting at is that these pages are called “man pages” in the Unix world, and I have included my own personal truncated variant here for your reading enjoyment. The thing is, many of these functions are way more general purpose than I’m letting on, but I’m only going to present the parts that are relevant for Internet Sockets Programming.
3363
3364But wait! That’s not all that’s wrong with my man pages:
3365
3366They are incomplete and only show the basics from the guide.
3367There are many more man pages than this in the real world.
3368They are different than the ones on your system.
3369The header files might be different for certain functions on your system.
3370The function parameters might be different for certain functions on your system.
3371If you want the real information, check your local Unix man pages by typing man whatever, where “whatever” is something that you’re incredibly interested in, such as “accept”. (I’m sure Microsoft Visual Studio has something similar in their help section. But “man” is better because it is one byte more concise than “help”. Unix wins again!)
3372
3373So, if these are so flawed, why even include them at all in the Guide? Well, there are a few reasons, but the best are that (a) these versions are geared specifically toward network programming and are easier to digest than the real ones, and (b) these versions contain examples!
3374
3375Oh! And speaking of the examples, I don’t tend to put in all the error checking because it really increases the length of the code. But you should absolutely do error checking pretty much any time you make any of the system calls unless you’re totally 100% sure it’s not going to fail, and you should probably do it even then!
3376
3377accept()
3378Accept an incoming connection on a listening socket
3379
3380Synopsis
3381 #include <sys/types.h>
3382 #include <sys/socket.h>
3383
3384 int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
3385Description
3386Once you’ve gone through the trouble of getting a SOCK_STREAM socket and setting it up for incoming connections with listen(), then you call accept() to actually get yourself a new socket descriptor to use for subsequent communication with the newly connected client.
3387
3388The old socket that you are using for listening is still there, and will be used for further accept() calls as they come in.
3389
3390Parameter Description
3391s The listen()ing socket descriptor.
3392addr This is filled in with the address of the site that’s connecting to you.
3393addrlen This is filled in with the sizeof() the structure returned in the addr parameter. You can safely ignore it if you assume you’re getting a struct sockaddr_in back, which you know you are, because that’s the type you passed in for addr.
3394accept() will normally block, and you can use select() to peek on the listening socket descriptor ahead of time to see if it’s “ready to read”. If so, then there’s a new connection waiting to be accept()ed! Yay! Alternatively, you could set the O_NONBLOCK flag on the listening socket using fcntl(), and then it will never block, choosing instead to return -1 with errno set to EWOULDBLOCK.
3395
3396The socket descriptor returned by accept() is a bona fide socket descriptor, open and connected to the remote host. You have to close() it when you’re done with it.
3397
3398Return Value
3399accept() returns the newly connected socket descriptor, or -1 on error, with errno set appropriately.
3400
3401Example
3402struct sockaddr_storage their_addr;
3403socklen_t addr_size;
3404struct addrinfo hints, *res;
3405int sockfd, new_fd;
3406
3407// first, load up address structs with getaddrinfo():
3408
3409memset(&hints, 0, sizeof hints);
3410hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
3411hints.ai_socktype = SOCK_STREAM;
3412hints.ai_flags = AI_PASSIVE; // fill in my IP for me
3413
3414getaddrinfo(NULL, MYPORT, &hints, &res);
3415
3416// make a socket, bind it, and listen on it:
3417
3418sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
3419bind(sockfd, res->ai_addr, res->ai_addrlen);
3420listen(sockfd, BACKLOG);
3421
3422// now accept an incoming connection:
3423
3424addr_size = sizeof their_addr;
3425new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
3426
3427// ready to communicate on socket descriptor new_fd!
3428See Also
3429socket(), getaddrinfo(), listen(), struct sockaddr_in
3430
3431bind()
3432Associate a socket with an IP address and port number
3433
3434Synopsis
3435 #include <sys/types.h>
3436 #include <sys/socket.h>
3437
3438 int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
3439Description
3440When a remote machine wants to connect to your server program, it needs two pieces of information: the IP address and the port number. The bind() call allows you to do just that.
3441
3442First, you call getaddrinfo() to load up a struct sockaddr with the destination address and port information. Then you call socket() to get a socket descriptor, and then you pass the socket and address into bind(), and the IP address and port are magically (using actual magic) bound to the socket!
3443
3444If you don’t know your IP address, or you know you only have one IP address on the machine, or you don’t care which of the machine’s IP addresses is used, you can simply pass the AI_PASSIVE flag in the hints parameter to getaddrinfo(). What this does is fill in the IP address part of the struct sockaddr with a special value that tells bind() that it should automatically fill in this host’s IP address.
3445
3446What what? What special value is loaded into the struct sockaddr’s IP address to cause it to auto-fill the address with the current host? I’ll tell you, but keep in mind this is only if you’re filling out the struct sockaddr by hand; if not, use the results from getaddrinfo(), as per above. In IPv4, the sin_addr.s_addr field of the struct sockaddr_in structure is set to INADDR_ANY. In IPv6, the sin6_addr field of the struct sockaddr_in6 structure is assigned into from the global variable in6addr_any. Or, if you’re declaring a new struct in6_addr, you can initialize it to IN6ADDR_ANY_INIT.
3447
3448Lastly, the addrlen parameter should be set to sizeof my_addr.
3449
3450Return Value
3451Returns zero on success, or -1 on error (and errno will be set accordingly).
3452
3453Example
3454// modern way of doing things with getaddrinfo()
3455
3456struct addrinfo hints, *res;
3457int sockfd;
3458
3459// first, load up address structs with getaddrinfo():
3460
3461memset(&hints, 0, sizeof hints);
3462hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
3463hints.ai_socktype = SOCK_STREAM;
3464hints.ai_flags = AI_PASSIVE; // fill in my IP for me
3465
3466getaddrinfo(NULL, "3490", &hints, &res);
3467
3468// make a socket:
3469// (you should actually walk the "res" linked list and error-check!)
3470
3471sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
3472
3473// bind it to the port we passed in to getaddrinfo():
3474
3475bind(sockfd, res->ai_addr, res->ai_addrlen);
3476// example of packing a struct by hand, IPv4
3477
3478struct sockaddr_in myaddr;
3479int s;
3480
3481myaddr.sin_family = AF_INET;
3482myaddr.sin_port = htons(3490);
3483
3484// you can specify an IP address:
3485inet_pton(AF_INET, "63.161.169.137", &(myaddr.sin_addr));
3486
3487// or you can let it automatically select one:
3488myaddr.sin_addr.s_addr = INADDR_ANY;
3489
3490s = socket(PF_INET, SOCK_STREAM, 0);
3491bind(s, (struct sockaddr*)&myaddr, sizeof myaddr);
3492See Also
3493getaddrinfo(), socket(), struct sockaddr_in, struct in_addr
3494
3495connect()
3496Connect a socket to a server
3497
3498Synopsis
3499 #include <sys/types.h>
3500 #include <sys/socket.h>
3501
3502 int connect(int sockfd, const struct sockaddr *serv_addr,
3503 socklen_t addrlen);
3504Description
3505Once you’ve built a socket descriptor with the socket() call, you can connect() that socket to a remote server using the well-named connect() system call. All you need to do is pass it the socket descriptor and the address of the server you’re interested in getting to know better. (Oh, and the length of the address, which is commonly passed to functions like this.)
3506
3507Usually this information comes along as the result of a call to getaddrinfo(), but you can fill out your own struct sockaddr if you want to.
3508
3509If you haven’t yet called bind() on the socket descriptor, it is automatically bound to your IP address and a random local port. This is usually just fine with you if you’re not a server, since you really don’t care what your local port is; you only care what the remote port is so you can put it in the serv_addr parameter. You can call bind() if you really want your client socket to be on a specific IP address and port, but this is pretty rare.
3510
3511Once the socket is connect()ed, you’re free to send() and recv() data on it to your heart’s content.
3512
3513Special note: if you connect() a SOCK_DGRAM UDP socket to a remote host, you can use send() and recv() as well as sendto() and recvfrom(). If you want.
3514
3515Return Value
3516Returns zero on success, or -1 on error (and errno will be set accordingly).
3517
3518Example
3519// connect to www.example.com port 80 (http)
3520
3521struct addrinfo hints, *res;
3522int sockfd;
3523
3524// first, load up address structs with getaddrinfo():
3525
3526memset(&hints, 0, sizeof hints);
3527hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
3528hints.ai_socktype = SOCK_STREAM;
3529
3530// we could put "80" instead on "http" on the next line:
3531getaddrinfo("www.example.com", "http", &hints, &res);
3532
3533// make a socket:
3534
3535sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
3536
3537// connect it to the address and port we passed in to getaddrinfo():
3538
3539connect(sockfd, res->ai_addr, res->ai_addrlen);
3540See Also
3541socket(), bind()
3542
3543close()
3544Close a socket descriptor
3545
3546Synopsis
3547 #include <unistd.h>
3548
3549 int close(int s);
3550Description
3551After you’ve finished using the socket for whatever demented scheme you have concocted and you don’t want to send() or recv() or, indeed, do anything else at all with the socket, you can close() it, and it’ll be freed up, never to be used again.
3552
3553The remote side can tell if this happens one of two ways. One: if the remote side calls recv(), it will return 0. Two: if the remote side calls send(), it’ll receive a signal SIGPIPE and send() will return -1 and errno will be set to EPIPE.
3554
3555Windows users: the function you need to use is called closesocket(), not close(). If you try to use close() on a socket descriptor, it’s possible Windows will get angry… And you wouldn’t like it when it’s angry.
3556
3557Return Value
3558Returns zero on success, or -1 on error (and errno will be set accordingly).
3559
3560Example
3561s = socket(PF_INET, SOCK_DGRAM, 0);
3562.
3563.
3564.
3565// a whole lotta stuff...*BRRRONNNN!*
3566.
3567.
3568.
3569close(s); // not much to it, really.
3570See Also
3571socket(), shutdown()
3572
3573getaddrinfo(), freeaddrinfo(), gai_strerror()
3574Get information about a host name and/or service and load up a struct sockaddr with the result.
3575
3576Synopsis
3577 #include <sys/types.h>
3578 #include <sys/socket.h>
3579 #include <netdb.h>
3580
3581 int getaddrinfo(const char *nodename, const char *servname,
3582 const struct addrinfo *hints, struct addrinfo **res);
3583
3584 void freeaddrinfo(struct addrinfo *ai);
3585
3586 const char *gai_strerror(int ecode);
3587
3588 struct addrinfo {
3589 int ai_flags; // AI_PASSIVE, AI_CANONNAME, ...
3590 int ai_family; // AF_xxx
3591 int ai_socktype; // SOCK_xxx
3592 int ai_protocol; // 0 (auto) or IPPROTO_TCP, IPPROTO_UDP
3593
3594 socklen_t ai_addrlen; // length of ai_addr
3595 char *ai_canonname; // canonical name for nodename
3596 struct sockaddr *ai_addr; // binary address
3597 struct addrinfo *ai_next; // next structure in linked list
3598 };
3599Description
3600getaddrinfo() is an excellent function that will return information on a particular host name (such as its IP address) and load up a struct sockaddr for you, taking care of the gritty details (like if it’s IPv4 or IPv6). It replaces the old functions gethostbyname() and getservbyname().The description, below, contains a lot of information that might be a little daunting, but actual usage is pretty simple. It might be worth it to check out the examples first.
3601
3602The host name that you’re interested in goes in the nodename parameter. The address can be either a host name, like “www.example.com”, or an IPv4 or IPv6 address (passed as a string). This parameter can also be NULL if you’re using the AI_PASSIVE flag (see below).
3603
3604The servname parameter is basically the port number. It can be a port number (passed as a string, like “80”), or it can be a service name, like “http” or “tftp” or “smtp” or “pop”, etc. Well-known service names can be found in the IANA Port List48 or in your /etc/services file.
3605
3606Lastly, for input parameters, we have hints. This is really where you get to define what the getaddrinfo() function is going to do. Zero the whole structure before use with memset(). Let’s take a look at the fields you need to set up before use.
3607
3608The ai_flags can be set to a variety of things, but here are a couple important ones. (Multiple flags can be specified by bitwise-ORing them together with the | operator). Check your man page for the complete list of flags.
3609
3610AI_CANONNAME causes the ai_canonname of the result to the filled out with the host’s canonical (real) name. AI_PASSIVE causes the result’s IP address to be filled out with INADDR_ANY (IPv4) or in6addr_any (IPv6); this causes a subsequent call to bind() to auto-fill the IP address of the struct sockaddr with the address of the current host. That’s excellent for setting up a server when you don’t want to hardcode the address.
3611
3612If you do use the AI_PASSIVE, flag, then you can pass NULL in the nodename (since bind() will fill it in for you later).
3613
3614Continuing on with the input paramters, you’ll likely want to set ai_family to AF_UNSPEC which tells getaddrinfo() to look for both IPv4 and IPv6 addresses. You can also restrict yourself to one or the other with AF_INET or AF_INET6.
3615
3616Next, the socktype field should be set to SOCK_STREAM or SOCK_DGRAM, depending on which type of socket you want.
3617
3618Finally, just leave ai_protocol at 0 to automatically choose your protocol type.
3619
3620Now, after you get all that stuff in there, you can finally make the call to getaddrinfo()!
3621
3622Of course, this is where the fun begins. The res will now point to a linked list of struct addrinfos, and you can go through this list to get all the addresses that match what you passed in with the hints.
3623
3624Now, it’s possible to get some addresses that don’t work for one reason or another, so what the Linux man page does is loops through the list doing a call to socket() and connect() (or bind() if you’re setting up a server with the AI_PASSIVE flag) until it succeeds.
3625
3626Finally, when you’re done with the linked list, you need to call freeaddrinfo() to free up the memory (or it will be leaked, and Some People will get upset).
3627
3628Return Value
3629Returns zero on success, or nonzero on error. If it returns nonzero, you can use the function gai_strerror() to get a printable version of the error code in the return value.
3630
3631Example
3632// code for a client connecting to a server
3633// namely a stream socket to www.example.com on port 80 (http)
3634// either IPv4 or IPv6
3635
3636int sockfd;
3637struct addrinfo hints, *servinfo, *p;
3638int rv;
3639
3640memset(&hints, 0, sizeof hints);
3641hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
3642hints.ai_socktype = SOCK_STREAM;
3643
3644if ((rv = getaddrinfo("www.example.com", "http", &hints, &servinfo)) != 0) {
3645 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
3646 exit(1);
3647}
3648
3649// loop through all the results and connect to the first we can
3650for(p = servinfo; p != NULL; p = p->ai_next) {
3651 if ((sockfd = socket(p->ai_family, p->ai_socktype,
3652 p->ai_protocol)) == -1) {
3653 perror("socket");
3654 continue;
3655 }
3656
3657 if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
3658 perror("connect");
3659 close(sockfd);
3660 continue;
3661 }
3662
3663 break; // if we get here, we must have connected successfully
3664}
3665
3666if (p == NULL) {
3667 // looped off the end of the list with no connection
3668 fprintf(stderr, "failed to connect\n");
3669 exit(2);
3670}
3671
3672freeaddrinfo(servinfo); // all done with this structure
3673// code for a server waiting for connections
3674// namely a stream socket on port 3490, on this host's IP
3675// either IPv4 or IPv6.
3676
3677int sockfd;
3678struct addrinfo hints, *servinfo, *p;
3679int rv;
3680
3681memset(&hints, 0, sizeof hints);
3682hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
3683hints.ai_socktype = SOCK_STREAM;
3684hints.ai_flags = AI_PASSIVE; // use my IP address
3685
3686if ((rv = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {
3687 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
3688 exit(1);
3689}
3690
3691// loop through all the results and bind to the first we can
3692for(p = servinfo; p != NULL; p = p->ai_next) {
3693 if ((sockfd = socket(p->ai_family, p->ai_socktype,
3694 p->ai_protocol)) == -1) {
3695 perror("socket");
3696 continue;
3697 }
3698
3699 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
3700 close(sockfd);
3701 perror("bind");
3702 continue;
3703 }
3704
3705 break; // if we get here, we must have connected successfully
3706}
3707
3708if (p == NULL) {
3709 // looped off the end of the list with no successful bind
3710 fprintf(stderr, "failed to bind socket\n");
3711 exit(2);
3712}
3713
3714freeaddrinfo(servinfo); // all done with this structure
3715See Also
3716gethostbyname(), getnameinfo()
3717
3718gethostname()
3719Returns the name of the system
3720
3721Synopsis
3722 #include <sys/unistd.h>
3723
3724 int gethostname(char *name, size_t len);
3725Description
3726Your system has a name. They all do. This is a slightly more Unixy thing than the rest of the networky stuff we’ve been talking about, but it still has its uses.
3727
3728For instance, you can get your host name, and then call gethostbyname() to find out your IP address.
3729
3730The parameter name should point to a buffer that will hold the host name, and len is the size of that buffer in bytes. gethostname() won’t overwrite the end of the buffer (it might return an error, or it might just stop writing), and it will NUL-terminate the string if there’s room for it in the buffer.
3731
3732Return Value
3733Returns zero on success, or -1 on error (and errno will be set accordingly).
3734
3735Example
3736char hostname[128];
3737
3738gethostname(hostname, sizeof hostname);
3739printf("My hostname: %s\n", hostname);
3740See Also
3741gethostbyname()
3742
3743gethostbyname(), gethostbyaddr()
3744Get an IP address for a hostname, or vice-versa
3745
3746Synopsis
3747 #include <sys/socket.h>
3748 #include <netdb.h>
3749
3750 struct hostent *gethostbyname(const char *name); // DEPRECATED!
3751 struct hostent *gethostbyaddr(const char *addr, int len, int type);
3752Description
3753PLEASE NOTE: these two functions are superseded by getaddrinfo() and getnameinfo()! In particular, gethostbyname() doesn’t work well with IPv6.
3754
3755These functions map back and forth between host names and IP addresses. For instance, if you have “www.example.com”, you can use gethostbyname() to get its IP address and store it in a struct in_addr.
3756
3757Conversely, if you have a struct in_addr or a struct in6_addr, you can use gethostbyaddr() to get the hostname back. gethostbyaddr() is IPv6 compatible, but you should use the newer shinier getnameinfo() instead.
3758
3759(If you have a string containing an IP address in dots-and-numbers format that you want to look up the hostname of, you’d be better off using getaddrinfo() with the AI_CANONNAME flag.)
3760
3761gethostbyname() takes a string like “www.yahoo.com”, and returns a struct hostent which contains tons of information, including the IP address. (Other information is the official host name, a list of aliases, the address type, the length of the addresses, and the list of addresses—it’s a general-purpose structure that’s pretty easy to use for our specific purposes once you see how.)
3762
3763gethostbyaddr() takes a struct in_addr or struct in6_addr and brings you up a corresponding host name (if there is one), so it’s sort of the reverse of gethostbyname(). As for parameters, even though addr is a char*, you actually want to pass in a pointer to a struct in_addr. len should be sizeof(struct in_addr), and type should be AF_INET.
3764
3765So what is this struct hostent that gets returned? It has a number of fields that contain information about the host in question.
3766
3767Field Description
3768char *h_name The real canonical host name.
3769char **h_aliases A list of aliases that can be accessed with arrays—the last element is NULL
3770int h_addrtype The result’s address type, which really should be AF_INET for our purposes.
3771int length The length of the addresses in bytes, which is 4 for IP (version 4) addresses.
3772char **h_addr_list A list of IP addresses for this host. Although this is a char**, it’s really an array of struct in_addr*s in disguise. The last array element is NULL.
3773h_addr A commonly defined alias for h_addr_list[0]. If you just want any old IP address for this host (yeah, they can have more than one) just use this field.
3774Return Value
3775Returns a pointer to a resultant struct hostent on success, or NULL on error.
3776
3777Instead of the normal perror() and all that stuff you’d normally use for error reporting, these functions have parallel results in the variable h_errno, which can be printed using the functions herror() or hstrerror(). These work just like the classic errno, perror(), and strerror() functions you’re used to.
3778
3779Example
3780// THIS IS A DEPRECATED METHOD OF GETTING HOST NAMES
3781// use getaddrinfo() instead!
3782
3783#include <stdio.h>
3784#include <errno.h>
3785#include <netdb.h>
3786#include <sys/types.h>
3787#include <sys/socket.h>
3788#include <netinet/in.h>
3789#include <arpa/inet.h>
3790
3791int main(int argc, char *argv[])
3792{
3793 int i;
3794 struct hostent *he;
3795 struct in_addr **addr_list;
3796
3797 if (argc != 2) {
3798 fprintf(stderr,"usage: ghbn hostname\n");
3799 return 1;
3800 }
3801
3802 if ((he = gethostbyname(argv[1])) == NULL) { // get the host info
3803 herror("gethostbyname");
3804 return 2;
3805 }
3806
3807 // print information about this host:
3808 printf("Official name is: %s\n", he->h_name);
3809 printf(" IP addresses: ");
3810 addr_list = (struct in_addr **)he->h_addr_list;
3811 for(i = 0; addr_list[i] != NULL; i++) {
3812 printf("%s ", inet_ntoa(*addr_list[i]));
3813 }
3814 printf("\n");
3815
3816 return 0;
3817}
3818// THIS HAS BEEN SUPERCEDED
3819// use getnameinfo() instead!
3820
3821struct hostent *he;
3822struct in_addr ipv4addr;
3823struct in6_addr ipv6addr;
3824
3825inet_pton(AF_INET, "192.0.2.34", &ipv4addr);
3826he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
3827printf("Host name: %s\n", he->h_name);
3828
3829inet_pton(AF_INET6, "2001:db8:63b3:1::beef", &ipv6addr);
3830he = gethostbyaddr(&ipv6addr, sizeof ipv6addr, AF_INET6);
3831printf("Host name: %s\n", he->h_name);
3832See Also
3833getaddrinfo(), getnameinfo(), gethostname(), errno, perror(), strerror(), struct in_addr
3834
3835getnameinfo()
3836Look up the host name and service name information for a given struct sockaddr.
3837
3838Synopsis
3839 #include <sys/socket.h>
3840 #include <netdb.h>
3841
3842 int getnameinfo(const struct sockaddr *sa, socklen_t salen,
3843 char *host, size_t hostlen,
3844 char *serv, size_t servlen, int flags);
3845Description
3846This function is the opposite of getaddrinfo(), that is, this function takes an already loaded struct sockaddr and does a name and service name lookup on it. It replaces the old gethostbyaddr() and getservbyport() functions.
3847
3848You have to pass in a pointer to a struct sockaddr (which in actuality is probably a struct sockaddr_in or struct sockaddr_in6 that you’ve cast) in the sa parameter, and the length of that struct in the salen.
3849
3850The resultant host name and service name will be written to the area pointed to by the host and serv parameters. Of course, you have to specify the max lengths of these buffers in hostlen and servlen.
3851
3852Finally, there are several flags you can pass, but here a a couple good ones. NI_NOFQDN will cause the host to only contain the host name, not the whole domain name. NI_NAMEREQD will cause the function to fail if the name cannot be found with a DNS lookup (if you don’t specify this flag and the name can’t be found, getnameinfo() will put a string version of the IP address in host instead).
3853
3854As always, check your local man pages for the full scoop.
3855
3856Return Value
3857Returns zero on success, or non-zero on error. If the return value is non-zero, it can be passed to gai_strerror() to get a human-readable string. See getaddrinfo for more information.
3858
3859Example
3860struct sockaddr_in6 sa; // could be IPv4 if you want
3861char host[1024];
3862char service[20];
3863
3864// pretend sa is full of good information about the host and port...
3865
3866getnameinfo(&sa, sizeof sa, host, sizeof host, service, sizeof service, 0);
3867
3868printf(" host: %s\n", host); // e.g. "www.example.com"
3869printf("service: %s\n", service); // e.g. "http"
3870See Also
3871getaddrinfo(), gethostbyaddr()
3872
3873getpeername()
3874Return address info about the remote side of the connection
3875
3876Synopsis
3877 #include <sys/socket.h>
3878
3879 int getpeername(int s, struct sockaddr *addr, socklen_t *len);
3880Description
3881Once you have either accept()ed a remote connection, or connect()ed to a server, you now have what is known as a peer. Your peer is simply the computer you’re connected to, identified by an IP address and a port. So…
3882
3883getpeername() simply returns a struct sockaddr_in filled with information about the machine you’re connected to.
3884
3885Why is it called a “name”? Well, there are a lot of different kinds of sockets, not just Internet Sockets like we’re using in this guide, and so “name” was a nice generic term that covered all cases. In our case, though, the peer’s “name” is it’s IP address and port.
3886
3887Although the function returns the size of the resultant address in len, you must preload len with the size of addr.
3888
3889Return Value
3890Returns zero on success, or -1 on error (and errno will be set accordingly).
3891
3892Example
3893// assume s is a connected socket
3894
3895socklen_t len;
3896struct sockaddr_storage addr;
3897char ipstr[INET6_ADDRSTRLEN];
3898int port;
3899
3900len = sizeof addr;
3901getpeername(s, (struct sockaddr*)&addr, &len);
3902
3903// deal with both IPv4 and IPv6:
3904if (addr.ss_family == AF_INET) {
3905 struct sockaddr_in *s = (struct sockaddr_in *)&addr;
3906 port = ntohs(s->sin_port);
3907 inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
3908} else { // AF_INET6
3909 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
3910 port = ntohs(s->sin6_port);
3911 inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
3912}
3913
3914printf("Peer IP address: %s\n", ipstr);
3915printf("Peer port : %d\n", port);
3916See Also
3917gethostname(), gethostbyname(), gethostbyaddr()
3918
3919errno
3920Holds the error code for the last system call
3921
3922Synopsis
3923 #include <errno.h>
3924
3925 int errno;
3926Description
3927This is the variable that holds error information for a lot of system calls. If you’ll recall, things like socket() and listen() return -1 on error, and they set the exact value of errno to let you know specifically which error occurred.
3928
3929The header file errno.h lists a bunch of constant symbolic names for errors, such as EADDRINUSE, EPIPE, ECONNREFUSED, etc. Your local man pages will tell you what codes can be returned as an error, and you can use these at run time to handle different errors in different ways.
3930
3931Or, more commonly, you can call perror() or strerror() to get a human-readable version of the error.
3932
3933One thing to note, for you multithreading enthusiasts, is that on most systems errno is defined in a threadsafe manner. (That is, it’s not actually a global variable, but it behaves just like a global variable would in a single-threaded environment.)
3934
3935Return Value
3936The value of the variable is the latest error to have transpired, which might be the code for “success” if the last action succeeded.
3937
3938Example
3939s = socket(PF_INET, SOCK_STREAM, 0);
3940if (s == -1) {
3941 perror("socket"); // or use strerror()
3942}
3943
3944tryagain:
3945if (select(n, &readfds, NULL, NULL) == -1) {
3946 // an error has occurred!!
3947
3948 // if we were only interrupted, just restart the select() call:
3949 if (errno == EINTR) goto tryagain; // AAAA! goto!!!
3950
3951 // otherwise it's a more serious error:
3952 perror("select");
3953 exit(1);
3954}
3955See Also
3956perror(), strerror()
3957
3958fcntl()
3959Control socket descriptors
3960
3961Synopsis
3962 #include <sys/unistd.h>
3963 #include <sys/fcntl.h>
3964
3965 int fcntl(int s, int cmd, long arg);
3966Description
3967This function is typically used to do file locking and other file-oriented stuff, but it also has a couple socket-related functions that you might see or use from time to time.
3968
3969Parameter s is the socket descriptor you wish to operate on, cmd should be set to F_SETFL, and arg can be one of the following commands. (Like I said, there’s more to fcntl() than I’m letting on here, but I’m trying to stay socket-oriented.)
3970
3971cmd Description
3972O_NONBLOCK Set the socket to be non-blocking. See the section on blocking for more details.
3973O_ASYNC Set the socket to do asynchronous I/O. When data is ready to be recv()’d on the socket, the signal SIGIO will be raised. This is rare to see, and beyond the scope of the guide. And I think it’s only available on certain systems.
3974Return Value
3975Returns zero on success, or -1 on error (and errno will be set accordingly).
3976
3977Different uses of the fcntl() system call actually have different return values, but I haven’t covered them here because they’re not socket-related. See your local fcntl() man page for more information.
3978
3979Example
3980int s = socket(PF_INET, SOCK_STREAM, 0);
3981
3982fcntl(s, F_SETFL, O_NONBLOCK); // set to non-blocking
3983fcntl(s, F_SETFL, O_ASYNC); // set to asynchronous I/O
3984See Also
3985Blocking, send()
3986
3987htons(), htonl(), ntohs(), ntohl()
3988Convert multi-byte integer types from host byte order to network byte order
3989
3990Synopsis
3991 #include <netinet/in.h>
3992
3993 uint32_t htonl(uint32_t hostlong);
3994 uint16_t htons(uint16_t hostshort);
3995 uint32_t ntohl(uint32_t netlong);
3996 uint16_t ntohs(uint16_t netshort);
3997Description
3998Just to make you really unhappy, different computers use different byte orderings internally for their multibyte integers (i.e. any integer that’s larger than a char). The upshot of this is that if you send() a two-byte short int from an Intel box to a Mac (before they became Intel boxes, too, I mean), what one computer thinks is the number 1, the other will think is the number 256, and vice-versa.
3999
4000The way to get around this problem is for everyone to put aside their differences and agree that Motorola and IBM had it right, and Intel did it the weird way, and so we all convert our byte orderings to “big-endian” before sending them out. Since Intel is a “little-endian” machine, it’s far more politically correct to call our preferred byte ordering “Network Byte Order”. So these functions convert from your native byte order to network byte order and back again.
4001
4002(This means on Intel these functions swap all the bytes around, and on PowerPC they do nothing because the bytes are already in Network Byte Order. But you should always use them in your code anyway, since someone might want to build it on an Intel machine and still have things work properly.)
4003
4004Note that the types involved are 32-bit (4 byte, probably int) and 16-bit (2 byte, very likely short) numbers. 64-bit machines might have a htonll() for 64-bit ints, but I’ve not seen it. You’ll just have to write your own.
4005
4006Anyway, the way these functions work is that you first decide if you’re converting from host (your machine’s) byte order or from network byte order. If “host”, the the first letter of the function you’re going to call is “h”. Otherwise it’s “n” for “network”. The middle of the function name is always “to” because you’re converting from one “to” another, and the penultimate letter shows what you’re converting to. The last letter is the size of the data, “s” for short, or “l” for long. Thus:
4007
4008Function Description
4009htons() host to network short
4010htonl() host to network long
4011ntohs() network to host short
4012ntohl() network to host long
4013Return Value
4014Each function returns the converted value.
4015
4016Example
4017uint32_t some_long = 10;
4018uint16_t some_short = 20;
4019
4020uint32_t network_byte_order;
4021
4022// convert and send
4023network_byte_order = htonl(some_long);
4024send(s, &network_byte_order, sizeof(uint32_t), 0);
4025
4026some_short == ntohs(htons(some_short)); // this expression is true
4027inet_ntoa(), inet_aton(), inet_addr
4028Convert IP addresses from a dots-and-number string to a struct in_addr and back
4029
4030Synopsis
4031 #include <sys/socket.h>
4032 #include <netinet/in.h>
4033 #include <arpa/inet.h>
4034
4035 // ALL THESE ARE DEPRECATED! Use inet_pton() or inet_ntop() instead!!
4036
4037 char *inet_ntoa(struct in_addr in);
4038 int inet_aton(const char *cp, struct in_addr *inp);
4039 in_addr_t inet_addr(const char *cp);
4040Description
4041These functions are deprecated because they don’t handle IPv6! Use inet_ntop() or inet_pton() instead! They are included here because they can still be found in the wild.
4042
4043All of these functions convert from a struct in_addr (part of your struct sockaddr_in, most likely) to a string in dots-and-numbers format (e.g. “192.168.5.10”) and vice-versa. If you have an IP address passed on the command line or something, this is the easiest way to get a struct in_addr to connect() to, or whatever. If you need more power, try some of the DNS functions like gethostbyname() or attempt a coup d’État in your local country.
4044
4045The function inet_ntoa() converts a network address in a struct in_addr to a dots-and-numbers format string. The “n” in “ntoa” stands for network, and the “a” stands for ASCII for historical reasons (so it’s “Network To ASCII”—the “toa” suffix has an analogous friend in the C library called atoi() which converts an ASCII string to an integer).
4046
4047The function inet_aton() is the opposite, converting from a dots-and-numbers string into a in_addr_t (which is the type of the field s_addr in your struct in_addr).
4048
4049Finally, the function inet_addr() is an older function that does basically the same thing as inet_aton(). It’s theoretically deprecated, but you’ll see it a lot and the police won’t come get you if you use it.
4050
4051Return Value
4052inet_aton() returns non-zero if the address is a valid one, and it returns zero if the address is invalid.
4053
4054inet_ntoa() returns the dots-and-numbers string in a static buffer that is overwritten with each call to the function.
4055
4056inet_addr() returns the address as an in_addr_t, or -1 if there’s an error. (That is the same result as if you tried to convert the string “255.255.255.255”, which is a valid IP address. This is why inet_aton() is better.)
4057
4058Example
4059struct sockaddr_in antelope;
4060char *some_addr;
4061
4062inet_aton("10.0.0.1", &antelope.sin_addr); // store IP in antelope
4063
4064some_addr = inet_ntoa(antelope.sin_addr); // return the IP
4065printf("%s\n", some_addr); // prints "10.0.0.1"
4066
4067// and this call is the same as the inet_aton() call, above:
4068antelope.sin_addr.s_addr = inet_addr("10.0.0.1");
4069See Also
4070inet_ntop(), inet_pton(), gethostbyname(), gethostbyaddr()
4071
4072inet_ntop(), inet_pton()
4073Convert IP addresses to human-readable form and back.
4074
4075Synopsis
4076 #include <arpa/inet.h>
4077
4078 const char *inet_ntop(int af, const void *src,
4079 char *dst, socklen_t size);
4080
4081 int inet_pton(int af, const char *src, void *dst);
4082Description
4083These functions are for dealing with human-readable IP addresses and converting them to their binary representation for use with various functions and system calls. The “n” stands for “network”, and “p” for “presentation”. Or “text presentation”. But you can think of it as “printable”. “ntop” is “network to printable”. See?
4084
4085Sometimes you don’t want to look at a pile of binary numbers when looking at an IP address. You want it in a nice printable form, like 192.0.2.180, or 2001:db8:8714:3a90::12. In that case, inet_ntop() is for you.
4086
4087inet_ntop() takes the address family in the af parameter (either AF_INET or AF_INET6). The src parameter should be a pointer to either a struct in_addr or struct in6_addr containing the address you wish to convert to a string. Finally dst and size are the pointer to the destination string and the maximum length of that string.
4088
4089What should the maximum length of the dst string be? What is the maximum length for IPv4 and IPv6 addresses? Fortunately there are a couple of macros to help you out. The maximum lengths are: INET_ADDRSTRLEN and INET6_ADDRSTRLEN.
4090
4091Other times, you might have a string containing an IP address in readable form, and you want to pack it into a struct sockaddr_in or a struct sockaddr_in6. In that case, the opposite funcion inet_pton() is what you’re after.
4092
4093inet_pton() also takes an address family (either AF_INET or AF_INET6) in the af parameter. The src parameter is a pointer to a string containing the IP address in printable form. Lastly the dst parameter points to where the result should be stored, which is probably a struct in_addr or struct in6_addr.
4094
4095These functions don’t do DNS lookups—you’ll need getaddrinfo() for that.
4096
4097Return Value
4098inet_ntop() returns the dst parameter on success, or NULL on failure (and errno is set).
4099
4100inet_pton() returns 1 on success. It returns -1 if there was an error (errno is set), or 0 if the input isn’t a valid IP address.
4101
4102Example
4103// IPv4 demo of inet_ntop() and inet_pton()
4104
4105struct sockaddr_in sa;
4106char str[INET_ADDRSTRLEN];
4107
4108// store this IP address in sa:
4109inet_pton(AF_INET, "192.0.2.33", &(sa.sin_addr));
4110
4111// now get it back and print it
4112inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);
4113
4114printf("%s\n", str); // prints "192.0.2.33"
4115// IPv6 demo of inet_ntop() and inet_pton()
4116// (basically the same except with a bunch of 6s thrown around)
4117
4118struct sockaddr_in6 sa;
4119char str[INET6_ADDRSTRLEN];
4120
4121// store this IP address in sa:
4122inet_pton(AF_INET6, "2001:db8:8714:3a90::12", &(sa.sin6_addr));
4123
4124// now get it back and print it
4125inet_ntop(AF_INET6, &(sa.sin6_addr), str, INET6_ADDRSTRLEN);
4126
4127printf("%s\n", str); // prints "2001:db8:8714:3a90::12"
4128// Helper function you can use:
4129
4130//Convert a struct sockaddr address to a string, IPv4 and IPv6:
4131
4132char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen)
4133{
4134 switch(sa->sa_family) {
4135 case AF_INET:
4136 inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
4137 s, maxlen);
4138 break;
4139
4140 case AF_INET6:
4141 inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
4142 s, maxlen);
4143 break;
4144
4145 default:
4146 strncpy(s, "Unknown AF", maxlen);
4147 return NULL;
4148 }
4149
4150 return s;
4151}
4152See Also
4153getaddrinfo()
4154
4155listen()
4156Tell a socket to listen for incoming connections
4157
4158Synopsis
4159 #include <sys/socket.h>
4160
4161 int listen(int s, int backlog);
4162Description
4163You can take your socket descriptor (made with the socket() system call) and tell it to listen for incoming connections. This is what differentiates the servers from the clients, guys.
4164
4165The backlog parameter can mean a couple different things depending on the system you on, but loosely it is how many pending connections you can have before the kernel starts rejecting new ones. So as the new connections come in, you should be quick to accept() them so that the backlog doesn’t fill. Try setting it to 10 or so, and if your clients start getting “Connection refused” under heavy load, set it higher.
4166
4167Before calling listen(), your server should call bind() to attach itself to a specific port number. That port number (on the server’s IP address) will be the one that clients connect to.
4168
4169Return Value
4170Returns zero on success, or -1 on error (and errno will be set accordingly).
4171
4172Example
4173struct addrinfo hints, *res;
4174int sockfd;
4175
4176// first, load up address structs with getaddrinfo():
4177
4178memset(&hints, 0, sizeof hints);
4179hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
4180hints.ai_socktype = SOCK_STREAM;
4181hints.ai_flags = AI_PASSIVE; // fill in my IP for me
4182
4183getaddrinfo(NULL, "3490", &hints, &res);
4184
4185// make a socket:
4186
4187sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
4188
4189// bind it to the port we passed in to getaddrinfo():
4190
4191bind(sockfd, res->ai_addr, res->ai_addrlen);
4192
4193listen(sockfd, 10); // set s up to be a server (listening) socket
4194
4195// then have an accept() loop down here somewhere
4196See Also
4197accept(), bind(), socket()
4198
4199perror(), strerror()
4200Print an error as a human-readable string
4201
4202Synopsis
4203 #include <stdio.h>
4204 #include <string.h> // for strerror()
4205
4206 void perror(const char *s);
4207 char *strerror(int errnum);
4208Description
4209Since so many functions return -1 on error and set the value of the variable errno to be some number, it would sure be nice if you could easily print that in a form that made sense to you.
4210
4211Mercifully, perror() does that. If you want more description to be printed before the error, you can point the parameter s to it (or you can leave s as NULL and nothing additional will be printed).
4212
4213In a nutshell, this function takes errno values, like ECONNRESET, and prints them nicely, like “Connection reset by peer.”
4214
4215The function strerror() is very similar to perror(), except it returns a pointer to the error message string for a given value (you usually pass in the variable errno).
4216
4217Return Value
4218strerror() returns a pointer to the error message string.
4219
4220Example
4221int s;
4222
4223s = socket(PF_INET, SOCK_STREAM, 0);
4224
4225if (s == -1) { // some error has occurred
4226 // prints "socket error: " + the error message:
4227 perror("socket error");
4228}
4229
4230// similarly:
4231if (listen(s, 10) == -1) {
4232 // this prints "an error: " + the error message from errno:
4233 printf("an error: %s\n", strerror(errno));
4234}
4235See Also
4236errno
4237
4238poll()
4239Test for events on multiple sockets simultaneously
4240
4241Synopsis
4242 #include <sys/poll.h>
4243
4244 int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
4245Description
4246This function is very similar to select() in that they both watch sets of file descriptors for events, such as incoming data ready to recv(), socket ready to send() data to, out-of-band data ready to recv(), errors, etc.
4247
4248The basic idea is that you pass an array of nfds struct pollfds in ufds, along with a timeout in milliseconds (1000 milliseconds in a second). The timeout can be negative if you want to wait forever. If no event happens on any of the socket descriptors by the timeout, poll() will return.
4249
4250Each element in the array of struct pollfds represents one socket descriptor, and contains the following fields:
4251
4252 struct pollfd {
4253 int fd; // the socket descriptor
4254 short events; // bitmap of events we're interested in
4255 short revents; // when poll() returns, bitmap of events that occurred
4256 };
4257Before calling poll(), load fd with the socket descriptor (if you set fd to a negative number, this struct pollfd is ignored and its revents field is set to zero) and then construct the events field by bitwise-ORing the following macros:
4258
4259Macro Description
4260POLLIN Alert me when data is ready to recv() on this socket.
4261POLLOUT Alert me when I can send() data to this socket without blocking.
4262POLLPRI Alert me when out-of-band data is ready to recv() on this socket.
4263Once the poll() call returns, the revents field will be constructed as a bitwise-OR of the above fields, telling you which descriptors actually have had that event occur. Additionally, these other fields might be present:
4264
4265Macro Description
4266POLLERR An error has occurred on this socket.
4267POLLHUP The remote side of the connection hung up.
4268POLLNVAL Something was wrong with the socket descriptor fd—maybe it’s uninitialized?
4269Return Value
4270Returns the number of elements in the ufds array that have had event occur on them; this can be zero if the timeout occurred. Also returns -1 on error (and errno will be set accordingly).
4271
4272Example
4273int s1, s2;
4274int rv;
4275char buf1[256], buf2[256];
4276struct pollfd ufds[2];
4277
4278s1 = socket(PF_INET, SOCK_STREAM, 0);
4279s2 = socket(PF_INET, SOCK_STREAM, 0);
4280
4281// pretend we've connected both to a server at this point
4282//connect(s1, ...)...
4283//connect(s2, ...)...
4284
4285// set up the array of file descriptors.
4286//
4287// in this example, we want to know when there's normal or out-of-band
4288// data ready to be recv()'d...
4289
4290ufds[0].fd = s1;
4291ufds[0].events = POLLIN | POLLPRI; // check for normal or out-of-band
4292
4293ufds[1].fd = s2;
4294ufds[1].events = POLLIN; // check for just normal data
4295
4296// wait for events on the sockets, 3.5 second timeout
4297rv = poll(ufds, 2, 3500);
4298
4299if (rv == -1) {
4300 perror("poll"); // error occurred in poll()
4301} else if (rv == 0) {
4302 printf("Timeout occurred! No data after 3.5 seconds.\n");
4303} else {
4304 // check for events on s1:
4305 if (ufds[0].revents & POLLIN) {
4306 recv(s1, buf1, sizeof buf1, 0); // receive normal data
4307 }
4308 if (ufds[0].revents & POLLPRI) {
4309 recv(s1, buf1, sizeof buf1, MSG_OOB); // out-of-band data
4310 }
4311
4312 // check for events on s2:
4313 if (ufds[1].revents & POLLIN) {
4314 recv(s1, buf2, sizeof buf2, 0);
4315 }
4316}
4317See Also
4318select()
4319
4320recv(), recvfrom()
4321Receive data on a socket
4322
4323Synopsis
4324 #include <sys/types.h>
4325 #include <sys/socket.h>
4326
4327 ssize_t recv(int s, void *buf, size_t len, int flags);
4328 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
4329 struct sockaddr *from, socklen_t *fromlen);
4330Description
4331Once you have a socket up and connected, you can read incoming data from the remote side using the recv() (for TCP SOCK_STREAM sockets) and recvfrom() (for UDP SOCK_DGRAM sockets).
4332
4333Both functions take the socket descriptor s, a pointer to the buffer buf, the size (in bytes) of the buffer len, and a set of flags that control how the functions work.
4334
4335Additionally, the recvfrom() takes a struct sockaddr*, from that will tell you where the data came from, and will fill in fromlen with the size of struct sockaddr. (You must also initialize fromlen to be the size of from or struct sockaddr.)
4336
4337So what wondrous flags can you pass into this function? Here are some of them, but you should check your local man pages for more information and what is actually supported on your system. You bitwise-or these together, or just set flags to 0 if you want it to be a regular vanilla recv().
4338
4339Macro Description
4340MSG_OOB Receive Out of Band data. This is how to get data that has been sent to you with the MSG_OOB flag in send(). As the receiving side, you will have had signal SIGURG raised telling you there is urgent data. In your handler for that signal, you could call recv() with this MSG_OOB flag.
4341MSG_PEEK If you want to call recv() “just for pretend”, you can call it with this flag. This will tell you what’s waiting in the buffer for when you call recv() “for real” (i.e. without the MSG_PEEK flag. It’s like a sneak preview into the next recv() call.
4342MSG_WAITALL Tell recv() to not return until all the data you specified in the len parameter. It will ignore your wishes in extreme circumstances, however, like if a signal interrupts the call or if some error occurs or if the remote side closes the connection, etc. Don’t be mad with it.
4343When you call recv(), it will block until there is some data to read. If you want to not block, set the socket to non-blocking or check with select() or poll() to see if there is incoming data before calling recv() or recvfrom().
4344
4345Return Value
4346Returns the number of bytes actually received (which might be less than you requested in the len parameter), or -1 on error (and errno will be set accordingly).
4347
4348If the remote side has closed the connection, recv() will return 0. This is the normal method for determining if the remote side has closed the connection. Normality is good, rebel!
4349
4350Example
4351// stream sockets and recv()
4352
4353struct addrinfo hints, *res;
4354int sockfd;
4355char buf[512];
4356int byte_count;
4357
4358// get host info, make socket, and connect it
4359memset(&hints, 0, sizeof hints);
4360hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
4361hints.ai_socktype = SOCK_STREAM;
4362getaddrinfo("www.example.com", "3490", &hints, &res);
4363sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
4364connect(sockfd, res->ai_addr, res->ai_addrlen);
4365
4366// all right! now that we're connected, we can receive some data!
4367byte_count = recv(sockfd, buf, sizeof buf, 0);
4368printf("recv()'d %d bytes of data in buf\n", byte_count);
4369// datagram sockets and recvfrom()
4370
4371struct addrinfo hints, *res;
4372int sockfd;
4373int byte_count;
4374socklen_t fromlen;
4375struct sockaddr_storage addr;
4376char buf[512];
4377char ipstr[INET6_ADDRSTRLEN];
4378
4379// get host info, make socket, bind it to port 4950
4380memset(&hints, 0, sizeof hints);
4381hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
4382hints.ai_socktype = SOCK_DGRAM;
4383hints.ai_flags = AI_PASSIVE;
4384getaddrinfo(NULL, "4950", &hints, &res);
4385sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
4386bind(sockfd, res->ai_addr, res->ai_addrlen);
4387
4388// no need to accept(), just recvfrom():
4389
4390fromlen = sizeof addr;
4391byte_count = recvfrom(sockfd, buf, sizeof buf, 0, &addr, &fromlen);
4392
4393printf("recv()'d %d bytes of data in buf\n", byte_count);
4394printf("from IP address %s\n",
4395 inet_ntop(addr.ss_family,
4396 addr.ss_family == AF_INET?
4397 ((struct sockadd_in *)&addr)->sin_addr:
4398 ((struct sockadd_in6 *)&addr)->sin6_addr,
4399 ipstr, sizeof ipstr);
4400See Also
4401send(), sendto(), select(), poll(), Blocking
4402
4403select()
4404Check if sockets descriptors are ready to read/write
4405
4406Synopsis
4407 #include <sys/select.h>
4408
4409 int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
4410 struct timeval *timeout);
4411
4412 FD_SET(int fd, fd_set *set);
4413 FD_CLR(int fd, fd_set *set);
4414 FD_ISSET(int fd, fd_set *set);
4415 FD_ZERO(fd_set *set);
4416Description
4417The select() function gives you a way to simultaneously check multiple sockets to see if they have data waiting to be recv()d, or if you can send() data to them without blocking, or if some exception has occurred.
4418
4419You populate your sets of socket descriptors using the macros, like FD_SET(), above. Once you have the set, you pass it into the function as one of the following parameters: readfds if you want to know when any of the sockets in the set is ready to recv() data, writefds if any of the sockets is ready to send() data to, and/or exceptfds if you need to know when an exception (error) occurs on any of the sockets. Any or all of these parameters can be NULL if you’re not interested in those types of events. After select() returns, the values in the sets will be changed to show which are ready for reading or writing, and which have exceptions.
4420
4421The first parameter, n is the highest-numbered socket descriptor (they’re just ints, remember?) plus one.
4422
4423Lastly, the struct timeval, timeout, at the end—this lets you tell select() how long to check these sets for. It’ll return after the timeout, or when an event occurs, whichever is first. The struct timeval has two fields: tv_sec is the number of seconds, to which is added tv_usec, the number of microseconds (1,000,000 microseconds in a second).
4424
4425The helper macros do the following:
4426
4427Macro Description
4428FD_SET(int fd, fd_set *set); Add fd to the set.
4429FD_CLR(int fd, fd_set *set); Remove fd from the set.
4430FD_ISSET(int fd, fd_set *set); Return true if fd is in the set.
4431FD_ZERO(fd_set *set); Clear all entries from the set.
4432Note for Linux users: Linux’s select() can return “ready-to-read” and then not actually be ready to read, thus causing the subsequent read() call to block. You can work around this bug by setting O_NONBLOCK flag on the receiving socket so it errors with EWOULDBLOCK, then ignoring this error if it occurs. See the fcntl() reference page for more info on setting a socket to non-blocking.
4433
4434Return Value
4435Returns the number of descriptors in the set on success, 0 if the timeout was reached, or -1 on error (and errno will be set accordingly). Also, the sets are modified to show which sockets are ready.
4436
4437Example
4438int s1, s2, n;
4439fd_set readfds;
4440struct timeval tv;
4441char buf1[256], buf2[256];
4442
4443// pretend we've connected both to a server at this point
4444//s1 = socket(...);
4445//s2 = socket(...);
4446//connect(s1, ...)...
4447//connect(s2, ...)...
4448
4449// clear the set ahead of time
4450FD_ZERO(&readfds);
4451
4452// add our descriptors to the set
4453FD_SET(s1, &readfds);
4454FD_SET(s2, &readfds);
4455
4456// since we got s2 second, it's the "greater", so we use that for
4457// the n param in select()
4458n = s2 + 1;
4459
4460// wait until either socket has data ready to be recv()d (timeout 10.5 secs)
4461tv.tv_sec = 10;
4462tv.tv_usec = 500000;
4463rv = select(n, &readfds, NULL, NULL, &tv);
4464
4465if (rv == -1) {
4466 perror("select"); // error occurred in select()
4467} else if (rv == 0) {
4468 printf("Timeout occurred! No data after 10.5 seconds.\n");
4469} else {
4470 // one or both of the descriptors have data
4471 if (FD_ISSET(s1, &readfds)) {
4472 recv(s1, buf1, sizeof buf1, 0);
4473 }
4474 if (FD_ISSET(s2, &readfds)) {
4475 recv(s2, buf2, sizeof buf2, 0);
4476 }
4477}
4478See Also
4479poll()
4480
4481setsockopt(), getsockopt()
4482Set various options for a socket
4483
4484Synopsis
4485 #include <sys/types.h>
4486 #include <sys/socket.h>
4487
4488 int getsockopt(int s, int level, int optname, void *optval,
4489 socklen_t *optlen);
4490 int setsockopt(int s, int level, int optname, const void *optval,
4491 socklen_t optlen);
4492Description
4493Sockets are fairly configurable beasts. In fact, they are so configurable, I’m not even going to cover it all here. It’s probably system-dependent anyway. But I will talk about the basics.
4494
4495Obviously, these functions get and set certain options on a socket. On a Linux box, all the socket information is in the man page for socket in section 7. (Type: “man 7 socket” to get all these goodies.)
4496
4497As for parameters, s is the socket you’re talking about, level should be set to SOL_SOCKET. Then you set the optname to the name you’re interested in. Again, see your man page for all the options, but here are some of the most fun ones:
4498
4499optname Description
4500SO_BINDTODEVICE Bind this socket to a symbolic device name like eth0 instead of using bind() to bind it to an IP address. Type the command ifconfig under Unix to see the device names.
4501SO_REUSEADDR Allows other sockets to bind() to this port, unless there is an active listening socket bound to the port already. This enables you to get around those “Address already in use” error messages when you try to restart your server after a crash.
4502SOCK_DGRAM Allows UDP datagram (SOCK_DGRAM) sockets to send and receive packets sent to and from the broadcast address. Does nothing—NOTHING!!—to TCP stream sockets! Hahaha!
4503As for the parameter optval, it’s usually a pointer to an int indicating the value in question. For booleans, zero is false, and non-zero is true. And that’s an absolute fact, unless it’s different on your system. If there is no parameter to be passed, optval can be NULL.
4504
4505The final parameter, optlen, should be set to the length of optval, probably sizeof(int), but varies depending on the option. Note that in the case of getsockopt(), this is a pointer to a socklen_t, and it specifies the maximum size object that will be stored in optval (to prevent buffer overflows). And getsockopt() will modify the value of optlen to reflect the number of bytes actually set.
4506
4507Warning: on some systems (notably Sun and Windows), the option can be a char instead of an int, and is set to, for example, a character value of '1' instead of an int value of 1. Again, check your own man pages for more info with “man setsockopt” and “man 7 socket”!
4508
4509Return Value
4510Returns zero on success, or -1 on error (and errno will be set accordingly).
4511
4512Example
4513int optval;
4514int optlen;
4515char *optval2;
4516
4517// set SO_REUSEADDR on a socket to true (1):
4518optval = 1;
4519setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
4520
4521// bind a socket to a device name (might not work on all systems):
4522optval2 = "eth1"; // 4 bytes long, so 4, below:
4523setsockopt(s2, SOL_SOCKET, SO_BINDTODEVICE, optval2, 4);
4524
4525// see if the SO_BROADCAST flag is set:
4526getsockopt(s3, SOL_SOCKET, SO_BROADCAST, &optval, &optlen);
4527if (optval != 0) {
4528 print("SO_BROADCAST enabled on s3!\n");
4529}
4530See Also
4531fcntl()
4532
4533send(), sendto()
4534Send data out over a socket
4535
4536Synopsis
4537 #include <sys/types.h>
4538 #include <sys/socket.h>
4539
4540 ssize_t send(int s, const void *buf, size_t len, int flags);
4541 ssize_t sendto(int s, const void *buf, size_t len,
4542 int flags, const struct sockaddr *to,
4543 socklen_t tolen);
4544Description
4545These functions send data to a socket. Generally speaking, send() is used for TCP SOCK_STREAM connected sockets, and sendto() is used for UDP SOCK_DGRAM unconnected datagram sockets. With the unconnected sockets, you must specify the destination of a packet each time you send one, and that’s why the last parameters of sendto() define where the packet is going.
4546
4547With both send() and sendto(), the parameter s is the socket, buf is a pointer to the data you want to send, len is the number of bytes you want to send, and flags allows you to specify more information about how the data is to be sent. Set flags to zero if you want it to be “normal” data. Here are some of the commonly used flags, but check your local send() man pages for more details:
4548
4549Macro Description
4550MSG_OOB Send as “out of band” data. TCP supports this, and it’s a way to tell the receiving system that this data has a higher priority than the normal data. The receiver will receive the signal SIGURG and it can then receive this data without first receiving all the rest of the normal data in the queue.
4551MSG_DONTROUTE Don’t send this data over a router, just keep it local.
4552MSG_DONTWAIT If send() would block because outbound traffic is clogged, have it return EAGAIN. This is like a “enable non-blocking just for this send.” See the section on blocking for more details.
4553MSG_NOSIGNAL If you send() to a remote host which is no longer recv()ing, you’ll typically get the signal SIGPIPE. Adding this flag prevents that signal from being raised.
4554Return Value
4555Returns the number of bytes actually sent, or -1 on error (and errno will be set accordingly). Note that the number of bytes actually sent might be less than the number you asked it to send! See the section on handling partial send()s for a helper function to get around this.
4556
4557Also, if the socket has been closed by either side, the process calling send() will get the signal SIGPIPE. (Unless send() was called with the MSG_NOSIGNAL flag.)
4558
4559Example
4560int spatula_count = 3490;
4561char *secret_message = "The Cheese is in The Toaster";
4562
4563int stream_socket, dgram_socket;
4564struct sockaddr_in dest;
4565int temp;
4566
4567// first with TCP stream sockets:
4568
4569// assume sockets are made and connected
4570//stream_socket = socket(...
4571//connect(stream_socket, ...
4572
4573// convert to network byte order
4574temp = htonl(spatula_count);
4575// send data normally:
4576send(stream_socket, &temp, sizeof temp, 0);
4577
4578// send secret message out of band:
4579send(stream_socket, secret_message, strlen(secret_message)+1, MSG_OOB);
4580
4581// now with UDP datagram sockets:
4582//getaddrinfo(...
4583//dest = ... // assume "dest" holds the address of the destination
4584//dgram_socket = socket(...
4585
4586// send secret message normally:
4587sendto(dgram_socket, secret_message, strlen(secret_message)+1, 0,
4588 (struct sockaddr*)&dest, sizeof dest);
4589See Also
4590recv(), recvfrom()
4591
4592shutdown()
4593Stop further sends and receives on a socket
4594
4595Synopsis
4596 #include <sys/socket.h>
4597
4598 int shutdown(int s, int how);
4599Description
4600That’s it! I’ve had it! No more send()s are allowed on this socket, but I still want to recv() data on it! Or vice-versa! How can I do this?
4601
4602When you close() a socket descriptor, it closes both sides of the socket for reading and writing, and frees the socket descriptor. If you just want to close one side or the other, you can use this shutdown() call.
4603
4604As for parameters, s is obviously the socket you want to perform this action on, and what action that is can be specified with the how parameter. How can be SHUT_RD to prevent further recv()s, SHUT_WR to prohibit further send()s, or SHUT_RDWR to do both.
4605
4606Note that shutdown() doesn’t free up the socket descriptor, so you still have to eventually close() the socket even if it has been fully shut down.
4607
4608This is a rarely used system call.
4609
4610Return Value
4611Returns zero on success, or -1 on error (and errno will be set accordingly).
4612
4613Example
4614int s = socket(PF_INET, SOCK_STREAM, 0);
4615
4616// ...do some send()s and stuff in here...
4617
4618// and now that we're done, don't allow any more sends()s:
4619shutdown(s, SHUT_WR);
4620See Also
4621close()
4622
4623socket()
4624Allocate a socket descriptor
4625
4626Synopsis
4627 #include <sys/types.h>
4628 #include <sys/socket.h>
4629
4630 int socket(int domain, int type, int protocol);
4631Description
4632Returns a new socket descriptor that you can use to do sockety things with. This is generally the first call in the whopping process of writing a socket program, and you can use the result for subsequent calls to listen(), bind(), accept(), or a variety of other functions.
4633
4634In usual usage, you get the values for these parameters from a call to getaddrinfo(), as shown in the example below. But you can fill them in by hand if you really want to.
4635
4636Macro Description
4637domain domain describes what kind of socket you’re interested in. This can, believe me, be a wide variety of things, but since this is a socket guide, it’s going to be PF_INET for IPv4, and PF_INET6 for IPv6.
4638type Also, the type parameter can be a number of things, but you’ll probably be setting it to either SOCK_STREAM for reliable TCP sockets (send(), recv()) or SOCK_DGRAM for unreliable fast UDP sockets (sendto(), recvfrom()). (Another interesting socket type is SOCK_RAW which can be used to construct packets by hand. It’s pretty cool.)
4639protocol Finally, the protocol parameter tells which protocol to use with a certain socket type. Like I’ve already said, for instance, SOCK_STREAM uses TCP. Fortunately for you, when using SOCK_STREAM or SOCK_DGRAM, you can just set the protocol to 0, and it’ll use the proper protocol automatically. Otherwise, you can use getprotobyname() to look up the proper protocol number.
4640Return Value
4641The new socket descriptor to be used in subsequent calls, or -1 on error (and errno will be set accordingly).
4642
4643Example
4644struct addrinfo hints, *res;
4645int sockfd;
4646
4647// first, load up address structs with getaddrinfo():
4648
4649memset(&hints, 0, sizeof hints);
4650hints.ai_family = AF_UNSPEC; // AF_INET, AF_INET6, or AF_UNSPEC
4651hints.ai_socktype = SOCK_STREAM; // SOCK_STREAM or SOCK_DGRAM
4652
4653getaddrinfo("www.example.com", "3490", &hints, &res);
4654
4655// make a socket using the information gleaned from getaddrinfo():
4656sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
4657See Also
4658accept(), bind(), getaddrinfo(), listen()
4659
4660struct sockaddr and pals
4661Structures for handling internet addresses
4662
4663Synopsis
4664 #include <netinet/in.h>
4665
4666 // All pointers to socket address structures are often cast to pointers
4667 // to this type before use in various functions and system calls:
4668
4669 struct sockaddr {
4670 unsigned short sa_family; // address family, AF_xxx
4671 char sa_data[14]; // 14 bytes of protocol address
4672 };
4673
4674
4675 // IPv4 AF_INET sockets:
4676
4677 struct sockaddr_in {
4678 short sin_family; // e.g. AF_INET, AF_INET6
4679 unsigned short sin_port; // e.g. htons(3490)
4680 struct in_addr sin_addr; // see struct in_addr, below
4681 char sin_zero[8]; // zero this if you want to
4682 };
4683
4684 struct in_addr {
4685 unsigned long s_addr; // load with inet_pton()
4686 };
4687
4688
4689 // IPv6 AF_INET6 sockets:
4690
4691 struct sockaddr_in6 {
4692 u_int16_t sin6_family; // address family, AF_INET6
4693 u_int16_t sin6_port; // port number, Network Byte Order
4694 u_int32_t sin6_flowinfo; // IPv6 flow information
4695 struct in6_addr sin6_addr; // IPv6 address
4696 u_int32_t sin6_scope_id; // Scope ID
4697 };
4698
4699 struct in6_addr {
4700 unsigned char s6_addr[16]; // load with inet_pton()
4701 };
4702
4703
4704 // General socket address holding structure, big enough to hold either
4705 // struct sockaddr_in or struct sockaddr_in6 data:
4706
4707 struct sockaddr_storage {
4708 sa_family_t ss_family; // address family
4709
4710 // all this is padding, implementation specific, ignore it:
4711 char __ss_pad1[_SS_PAD1SIZE];
4712 int64_t __ss_align;
4713 char __ss_pad2[_SS_PAD2SIZE];
4714 };
4715Description
4716These are the basic structures for all syscalls and functions that deal with internet addresses. Often you’ll use getaddrinfo() to fill these structures out, and then will read them when you have to.
4717
4718In memory, the struct sockaddr_in and struct sockaddr_in6 share the same beginning structure as struct sockaddr, and you can freely cast the pointer of one type to the other without any harm, except the possible end of the universe.
4719
4720Just kidding on that end-of-the-universe thing…if the universe does end when you cast a struct sockaddr_in* to a struct sockaddr*, I promise you it’s pure coincidence and you shouldn’t even worry about it.
4721
4722So, with that in mind, remember that whenever a function says it takes a struct sockaddr* you can cast your struct sockaddr_in*, struct sockaddr_in6*, or struct sockadd_storage* to that type with ease and safety.
4723
4724struct sockaddr_in is the structure used with IPv4 addresses (e.g. “192.0.2.10”). It holds an address family (AF_INET), a port in sin_port, and an IPv4 address in sin_addr.
4725
4726There’s also this sin_zero field in struct sockaddr_in which some people claim must be set to zero. Other people don’t claim anything about it (the Linux documentation doesn’t even mention it at all), and setting it to zero doesn’t seem to be actually necessary. So, if you feel like it, set it to zero using memset().
4727
4728Now, that struct in_addr is a weird beast on different systems. Sometimes it’s a crazy union with all kinds of #defines and other nonsense. But what you should do is only use the s_addr field in this structure, because many systems only implement that one.
4729
4730struct sockadd_in6 and struct in6_addr are very similar, except they’re used for IPv6.
4731
4732struct sockaddr_storage is a struct you can pass to accept() or recvfrom() when you’re trying to write IP version-agnostic code and you don’t know if the new address is going to be IPv4 or IPv6. The struct sockaddr_storage structure is large enough to hold both types, unlike the original small struct sockaddr.
4733
4734Example
4735// IPv4:
4736
4737struct sockaddr_in ip4addr;
4738int s;
4739
4740ip4addr.sin_family = AF_INET;
4741ip4addr.sin_port = htons(3490);
4742inet_pton(AF_INET, "10.0.0.1", &ip4addr.sin_addr);
4743
4744s = socket(PF_INET, SOCK_STREAM, 0);
4745bind(s, (struct sockaddr*)&ip4addr, sizeof ip4addr);
4746// IPv6:
4747
4748struct sockaddr_in6 ip6addr;
4749int s;
4750
4751ip6addr.sin6_family = AF_INET6;
4752ip6addr.sin6_port = htons(4950);
4753inet_pton(AF_INET6, "2001:db8:8714:3a90::12", &ip6addr.sin6_addr);
4754
4755s = socket(PF_INET6, SOCK_STREAM, 0);
4756bind(s, (struct sockaddr*)&ip6addr, sizeof ip6addr);
4757See Also
4758accept(), bind(), connect(), inet_aton(), inet_ntoa()
4759
4760More References
4761You’ve come this far, and now you’re screaming for more! Where else can you go to learn more about all this stuff?
4762
4763Books
4764For old-school actual hold-it-in-your-hand pulp paper books, try some of the following excellent books. These redirect to affiliate links with a popular bookseller, giving me nice kickbacks. If you’re merely feeling generous, you can paypal a donation to beej@beej.us. :-)
4765
4766Unix Network Programming, volumes 1-2 by W. Richard Stevens. Published by Addison-Wesley Professional and Prentice Hall. ISBNs for volumes 1-2: 978-013141155549, 978-013081081650.
4767
4768Internetworking with TCP/IP, volume I by Douglas E. Comer. Published by Pearson. ISBN 978-013608530051.
4769
4770TCP/IP Illustrated, volumes 1-3 by W. Richard Stevens and Gary R. Wright. Published by Addison Wesley. ISBNs for volumes 1, 2, and 3 (and a 3-volume set): 978-020163346752, 978-020163354253, 978-020163495254, (978-020177631755).
4771
4772TCP/IP Network Administration by Craig Hunt. Published by O’Reilly & Associates, Inc. ISBN 978-059600297856.
4773
4774Advanced Programming in the UNIX Environment by W. Richard Stevens. Published by Addison Wesley. ISBN 978-032163773457.
4775
4776Web References
4777On the web:
4778
4779BSD Sockets: A Quick And Dirty Primer58 (Unix system programming info, too!)
4780
4781The Unix Socket FAQ59
4782
4783TCP/IP FAQ60
4784
4785The Winsock FAQ61
4786
4787And here are some relevant Wikipedia pages:
4788
4789Berkeley Sockets62
4790
4791Internet Protocol (IP)63
4792
4793Transmission Control Protocol (TCP)64
4794
4795User Datagram Protocol (UDP)65
4796
4797Client-Server66
4798
4799Serialization67 (packing and unpacking data)
4800
4801RFCs
4802RFCs68—the real dirt! These are documents that describe assigned numbers, programming APIs, and protocols that are used on the Internet. I’ve included links to a few of them here for your enjoyment, so grab a bucket of popcorn and put on your thinking cap:
4803
4804RFC 169 —The First RFC; this gives you an idea of what the “Internet” was like just as it was coming to life, and an insight into how it was being designed from the ground up. (This RFC is completely obsolete, obviously!)
4805
4806RFC 76870 —The User Datagram Protocol (UDP)
4807
4808RFC 79171 —The Internet Protocol (IP)
4809
4810RFC 79372 —The Transmission Control Protocol (TCP)
4811
4812RFC 85473 —The Telnet Protocol
4813
4814RFC 95974 —File Transfer Protocol (FTP)
4815
4816RFC 135075 —The Trivial File Transfer Protocol (TFTP)
4817
4818RFC 145976 —Internet Relay Chat Protocol (IRC)
4819
4820RFC 191877 —Address Allocation for Private Internets
4821
4822RFC 213178 —Dynamic Host Configuration Protocol (DHCP)
4823
4824RFC 261679 —Hypertext Transfer Protocol (HTTP)
4825
4826RFC 282180 —Simple Mail Transfer Protocol (SMTP)
4827
4828RFC 333081 —Special-Use IPv4 Addresses
4829
4830RFC 349382 —Basic Socket Interface Extensions for IPv6
4831
4832RFC 354283 —Advanced Sockets Application Program Interface (API) for IPv6
4833
4834RFC 384984 —IPv6 Address Prefix Reserved for Documentation
4835
4836RFC 392085 —Extensible Messaging and Presence Protocol (XMPP)
4837
4838RFC 397786 —Network News Transfer Protocol (NNTP)
4839
4840RFC 419387 —Unique Local IPv6 Unicast Addresses
4841
4842RFC 450688 —External Data Representation Standard (XDR)
4843
4844The IETF has a nice online tool for searching and browsing RFCs89.
4845
4846https://www.linux.com/↩︎
4847
4848https://bsd.org/↩︎
4849
4850https://cygwin.com/↩︎
4851
4852https://docs.microsoft.com/en-us/windows/wsl/about↩︎
4853
4854https://tangentsoft.net/wskfaq/↩︎
4855
4856http://www.catb.org/~esr/faqs/smart-questions.html↩︎
4857
4858https://beej.us/guide/bgnet/examples/telnot.c↩︎
4859
4860https://tools.ietf.org/html/rfc854↩︎
4861
4862https://tools.ietf.org/html/rfc793↩︎
4863
4864https://tools.ietf.org/html/rfc791↩︎
4865
4866https://tools.ietf.org/html/rfc768↩︎
4867
4868https://tools.ietf.org/html/rfc791↩︎
4869
4870https://en.wikipedia.org/wiki/Vint_Cerf↩︎
4871
4872https://en.wikipedia.org/wiki/ELIZA↩︎
4873
4874https://www.iana.org/assignments/port-numbers↩︎
4875
4876https://en.wikipedia.org/wiki/Doom_(1993_video_game)↩︎
4877
4878https://en.wikipedia.org/wiki/Wilford_Brimley↩︎
4879
4880https://tools.ietf.org/html/rfc1918↩︎
4881
4882https://tools.ietf.org/html/rfc4193↩︎
4883
4884https://www.iana.org/assignments/port-numbers↩︎
4885
4886https://beej.us/guide/bgnet/examples/showip.c↩︎
4887
4888https://tools.ietf.org/html/rfc1413↩︎
4889
4890https://beej.us/guide/bgnet/examples/server.c↩︎
4891
4892https://beej.us/guide/bgnet/examples/client.c↩︎
4893
4894https://beej.us/guide/bgnet/examples/listener.c↩︎
4895
4896https://beej.us/guide/bgnet/examples/talker.c↩︎
4897
4898https://libevent.org/↩︎
4899
4900https://beej.us/guide/bgnet/examples/poll.c↩︎
4901
4902https://beej.us/guide/bgnet/examples/pollserver.c↩︎
4903
4904https://libevent.org/↩︎
4905
4906https://beej.us/guide/bgnet/examples/select.c↩︎
4907
4908https://beej.us/guide/bgnet/examples/selectserver.c↩︎
4909
4910https://en.wikipedia.org/wiki/Internet_Relay_Chat↩︎
4911
4912https://beej.us/guide/bgnet/examples/pack.c↩︎
4913
4914https://en.wikipedia.org/wiki/IEEE_754↩︎
4915
4916https://beej.us/guide/bgnet/examples/ieee754.c↩︎
4917
4918https://beej.us/guide/url/tpop↩︎
4919
4920https://github.com/protobuf-c/protobuf-c↩︎
4921
4922https://beej.us/guide/bgnet/examples/pack2.c↩︎
4923
4924https://beej.us/guide/bgnet/examples/pack2.c↩︎
4925
4926https://tools.ietf.org/html/rfc4506↩︎
4927
4928https://beej.us/guide/bgnet/examples/broadcaster.c↩︎
4929
4930http://www.unpbook.com/src.html↩︎
4931
4932http://www.unpbook.com/src.html↩︎
4933
4934https://www.openssl.org/↩︎
4935
4936https://stackoverflow.com/questions/21323023/↩︎
4937
4938https://www.iana.org/assignments/port-numbers↩︎
4939
4940https://www.iana.org/assignments/port-numbers↩︎
4941
4942https://beej.us/guide/url/unixnet1↩︎
4943
4944https://beej.us/guide/url/unixnet2↩︎
4945
4946https://beej.us/guide/url/intertcp1↩︎
4947
4948https://beej.us/guide/url/tcpi1↩︎
4949
4950https://beej.us/guide/url/tcpi2↩︎
4951
4952https://beej.us/guide/url/tcpi3↩︎
4953
4954https://beej.us/guide/url/tcpi123↩︎
4955
4956https://beej.us/guide/url/tcpna↩︎
4957
4958https://beej.us/guide/url/advunix↩︎
4959
4960https://cis.temple.edu/~giorgio/old/cis307s96/readings/docs/sockets.html↩︎
4961
4962https://developerweb.net/?f=70↩︎
4963
4964http://www.faqs.org/faqs/internet/tcp-ip/tcp-ip-faq/part1/↩︎
4965
4966https://tangentsoft.net/wskfaq/↩︎
4967
4968https://en.wikipedia.org/wiki/Berkeley_sockets↩︎
4969
4970https://en.wikipedia.org/wiki/Internet_Protocol↩︎
4971
4972https://en.wikipedia.org/wiki/Transmission_Control_Protocol↩︎
4973
4974https://en.wikipedia.org/wiki/User_Datagram_Protocol↩︎
4975
4976https://en.wikipedia.org/wiki/Client-server↩︎
4977
4978https://en.wikipedia.org/wiki/Serialization↩︎
4979
4980https://www.rfc-editor.org/↩︎
4981
4982https://tools.ietf.org/html/rfc1↩︎
4983
4984https://tools.ietf.org/html/rfc768↩︎
4985
4986https://tools.ietf.org/html/rfc791↩︎
4987
4988https://tools.ietf.org/html/rfc793↩︎
4989
4990https://tools.ietf.org/html/rfc854↩︎
4991
4992https://tools.ietf.org/html/rfc959↩︎
4993
4994https://tools.ietf.org/html/rfc1350↩︎
4995
4996https://tools.ietf.org/html/rfc1459↩︎
4997
4998https://tools.ietf.org/html/rfc1918↩︎
4999
5000https://tools.ietf.org/html/rfc2131↩︎
5001
5002https://tools.ietf.org/html/rfc2616↩︎
5003
5004https://tools.ietf.org/html/rfc2821↩︎
5005
5006https://tools.ietf.org/html/rfc3330↩︎
5007
5008https://tools.ietf.org/html/rfc3493↩︎
5009
5010https://tools.ietf.org/html/rfc3542↩︎
5011
5012https://tools.ietf.org/html/rfc3849↩︎
5013
5014https://tools.ietf.org/html/rfc3920↩︎
5015
5016https://tools.ietf.org/html/rfc3977↩︎
5017
5018https://tools.ietf.org/html/rfc4193↩︎
5019
5020https://tools.ietf.org/html/rfc4506↩︎
5021
5022https://tools.ietf.org/rfc/↩︎