Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-doc
Path: blob/main/documentation/content/en/books/developers-handbook/sockets/_index.po
18099 views
# SOME DESCRIPTIVE TITLE
# Copyright (C) YEAR The FreeBSD Project
# This file is distributed under the same license as the FreeBSD Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: FreeBSD Documentation VERSION\n"
"POT-Creation-Date: 2026-02-22 15:58+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#. type: YAML Front Matter: description
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1
#, no-wrap
msgid "FreeBSD Sockets"
msgstr ""

#. type: YAML Front Matter: title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1
#, no-wrap
msgid "Chapter 7. Sockets"
msgstr ""

#. type: Title =
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:16
#, no-wrap
msgid "Sockets"
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:54
#, no-wrap
msgid "Synopsis"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:59
msgid ""
"BSD sockets take interprocess communications to a new level.  It is no "
"longer necessary for the communicating processes to run on the same "
"machine.  They still _can_, but they do not have to."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:62
msgid ""
"Not only do these processes not have to run on the same machine, they do not "
"have to run under the same operating system.  Thanks to BSD sockets, your "
"FreeBSD software can smoothly cooperate with a program running on a "
"Macintosh(R), another one running on a Sun(TM) workstation, yet another one "
"running under Windows(R) 2000, all connected with an Ethernet-based local "
"area network."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:64
msgid ""
"But your software can equally well cooperate with processes running in "
"another building, or on another continent, inside a submarine, or a space "
"shuttle."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:67
msgid ""
"It can also cooperate with processes that are not part of a computer (at "
"least not in the strict sense of the word), but of such devices as printers, "
"digital cameras, medical equipment.  Just about anything capable of digital "
"communications."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:69
#, no-wrap
msgid "Networking and Diversity"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:75
msgid ""
"We have already hinted on the _diversity_ of networking.  Many different "
"systems have to talk to each other.  And they have to speak the same "
"language.  They also have to _understand_ the same language the same way."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:80
msgid ""
"People often think that _body language_ is universal.  But it is not.  Back "
"in my early teens, my father took me to Bulgaria.  We were sitting at a "
"table in a park in Sofia, when a vendor approached us trying to sell us some "
"roasted almonds."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:83
msgid ""
"I had not learned much Bulgarian by then, so, instead of saying no, I shook "
"my head from side to side, the \"universal\" body language for _no_.  The "
"vendor quickly started serving us some almonds."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:91
msgid ""
"I then remembered I had been told that in Bulgaria shaking your head "
"sideways meant _yes_.  Quickly, I started nodding my head up and down.  The "
"vendor noticed, took his almonds, and walked away.  To an uninformed "
"observer, I did not change the body language: I continued using the language "
"of shaking and nodding my head.  What changed was the _meaning_ of the body "
"language.  At first, the vendor and I interpreted the same language as "
"having completely different meaning.  I had to adjust my own interpretation "
"of that language so the vendor would understand."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:95
msgid ""
"It is the same with computers: The same symbols may have different, even "
"outright opposite meaning.  Therefore, for two computers to understand each "
"other, they must not only agree on the same _language_, but on the same "
"_interpretation_ of the language."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:97
#, no-wrap
msgid "Protocols"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:104
msgid ""
"While various programming languages tend to have complex syntax and use a "
"number of multi-letter reserved words (which makes them easy for the human "
"programmer to understand), the languages of data communications tend to be "
"very terse.  Instead of multi-byte words, they often use individual _bits_.  "
"There is a very convincing reason for it: While data travels _inside_ your "
"computer at speeds approaching the speed of light, it often travels "
"considerably slower between two computers."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:106
msgid ""
"As the languages used in data communications are so terse, we usually refer "
"to them as _protocols_ rather than languages."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:111
msgid ""
"As data travels from one computer to another, it always uses more than one "
"protocol.  These protocols are _layered_.  The data can be compared to the "
"inside of an onion: You have to peel off several layers of \"skin\" to get "
"to the data.  This is best illustrated with a picture:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:112
#, no-wrap
msgid "Protocol Layers"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:113
#, no-wrap
msgid "layers.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:116
msgid ""
"In this example, we are trying to get an image from a web page we are "
"connected to via an Ethernet."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:119
msgid ""
"The image consists of raw data, which is simply a sequence of RGB values "
"that our software can process, i.e., convert into an image and display on "
"our monitor."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:124
msgid ""
"Alas, our software has no way of knowing how the raw data is organized: Is "
"it a sequence of RGB values, or a sequence of grayscale intensities, or "
"perhaps of CMYK encoded colors? Is the data represented by 8-bit quanta, or "
"are they 16 bits in size, or perhaps 4 bits? How many rows and columns does "
"the image consist of? Should certain pixels be transparent?"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:126
msgid "I think you get the picture..."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:129
msgid ""
"To inform our software how to handle the raw data, it is encoded as a PNG "
"file.  It could be a GIF, or a JPEG, but it is a PNG."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:131
msgid "And PNG is a protocol."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:133
msgid ""
"At this point, I can hear some of you yelling, _\"No, it is not! It is a "
"file format!\"_"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:138
msgid ""
"Well, of course it is a file format.  But from the perspective of data "
"communications, a file format is a protocol: The file structure is a "
"_language_, a terse one at that, communicating to our _process_ how the data "
"is organized.  Ergo, it is a _protocol_."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:141
msgid ""
"Alas, if all we received was the PNG file, our software would be facing a "
"serious problem: How is it supposed to know the data is representing an "
"image, as opposed to some text, or perhaps a sound, or what not? Secondly, "
"how is it supposed to know the image is in the PNG format as opposed to GIF, "
"or JPEG, or some other image format?"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:145
msgid ""
"To obtain that information, we are using another protocol: HTTP.  This "
"protocol can tell us exactly that the data represents an image, and that it "
"uses the PNG protocol.  It can also tell us some other things, but let us "
"stay focused on protocol layers here."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:148
msgid ""
"So, now we have some data wrapped in the PNG protocol, wrapped in the HTTP "
"protocol.  How did we get it from the server?"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:152
msgid ""
"By using TCP/IP over Ethernet, that is how.  Indeed, that is three more "
"protocols.  Instead of continuing inside out, I am now going to talk about "
"Ethernet, simply because it is easier to explain the rest that way."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:156
msgid ""
"Ethernet is an interesting system of connecting computers in a _local area "
"network_ (LAN).  Each computer has a _network interface card_ (NIC), which "
"has a unique 48-bit ID called its _address_.  No two Ethernet NICs in the "
"world have the same address."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:162
msgid ""
"These NICs are all connected with each other.  Whenever one computer wants "
"to communicate with another in the same Ethernet LAN, it sends a message "
"over the network.  Every NIC sees the message.  But as part of the Ethernet "
"_protocol_, the data contains the address of the destination NIC (among "
"other things).  So, only one of all the network interface cards will pay "
"attention to it, the rest will ignore it."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:166
msgid ""
"But not all computers are connected to the same network.  Just because we "
"have received the data over our Ethernet does not mean it originated in our "
"own local area network.  It could have come to us from some other network "
"(which may not even be Ethernet based) connected with our own network via "
"the Internet."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:170
msgid ""
"All data is transferred over the Internet using IP, which stands for "
"_Internet Protocol_.  Its basic role is to let us know where in the world "
"the data has arrived from, and where it is supposed to go to.  It does not "
"_guarantee_ we will receive the data, only that we will know where it came "
"from _if_ we do receive it."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:173
msgid ""
"Even if we do receive the data, IP does not guarantee we will receive "
"various chunks of data in the same order the other computer has sent it to "
"us.  So, we can receive the center of our image before we receive the upper "
"left corner and after the lower right, for example."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:175
msgid ""
"It is TCP (_Transmission Control Protocol_) that asks the sender to resend "
"any lost data and that places it all into the proper order."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:178
msgid ""
"All in all, it took _five_ different protocols for one computer to "
"communicate to another what an image looks like.  We received the data "
"wrapped into the PNG protocol, which was wrapped into the HTTP protocol, "
"which was wrapped into the TCP protocol, which was wrapped into the IP "
"protocol, which was wrapped into the Ethernet protocol."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:182
msgid ""
"Oh, and by the way, there probably were several other protocols involved "
"somewhere on the way.  For example, if our LAN was connected to the Internet "
"through a dial-up call, it used the PPP protocol over the modem which used "
"one (or several) of the various modem protocols, et cetera, et cetera, et "
"cetera..."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:184
msgid ""
"As a developer you should be asking by now, _\"How am I supposed to handle "
"it all?\"_"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:189
msgid ""
"Luckily for you, you are _not_ supposed to handle it all.  You _are_ "
"supposed to handle some of it, but not all of it.  Specifically, you need "
"not worry about the physical connection (in our case Ethernet and possibly "
"PPP, etc).  Nor do you need to handle the Internet Protocol, or the "
"Transmission Control Protocol."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:192
msgid ""
"In other words, you do not have to do anything to receive the data from the "
"other computer.  Well, you do have to _ask_ for it, but that is almost as "
"simple as opening a file."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:195
msgid ""
"Once you have received the data, it is up to you to figure out what to do "
"with it.  In our case, you would need to understand the HTTP protocol and "
"the PNG file structure."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:199
msgid ""
"To use an analogy, all the internetworking protocols become a gray area: Not "
"so much because we do not understand how it works, but because we are no "
"longer concerned about it.  The sockets interface takes care of this gray "
"area for us:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:200
#, no-wrap
msgid "Sockets Covered Protocol Layers"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:201
#, no-wrap
msgid "slayers.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:204
msgid ""
"We only need to understand any protocols that tell us how to _interpret the "
"data_, not how to _receive_ it from another process, nor how to _send_ it to "
"another process."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:206
#, no-wrap
msgid "The Sockets Model"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:211
msgid ""
"BSD sockets are built on the basic UNIX(R) model: _Everything is a file._ In "
"our example, then, sockets would let us receive an _HTTP file_, so to "
"speak.  It would then be up to us to extract the _PNG file_ from it."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:214
msgid ""
"Due to the complexity of internetworking, we cannot just use the `open` "
"system call, or the `open()` C function.  Instead, we need to take several "
"steps to \"opening\" a socket."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:217
msgid ""
"Once we do, however, we can start treating the _socket_ the same way we "
"treat any _file descriptor_: We can `read` from it, `write` to it, `pipe` "
"it, and, eventually, `close` it."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:219
#, no-wrap
msgid "Essential Socket Functions"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:223
msgid ""
"While FreeBSD offers different functions to work with sockets, we only "
"_need_ four to \"open\" a socket.  And in some cases we only need two."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:225
#, no-wrap
msgid "The Client-Server Difference"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:228
msgid ""
"Typically, one of the ends of a socket-based data communication is a "
"_server_, the other is a _client_."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:230
#, no-wrap
msgid "The Common Elements"
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:233
#, no-wrap
msgid "`socket`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:237
msgid ""
"The one function used by both, clients and servers, is man:socket[2].  It is "
"declared this way:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:241
#, no-wrap
msgid "int socket(int domain, int type, int protocol);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:246
msgid ""
"The return value is of the same type as that of `open`, an integer.  FreeBSD "
"allocates its value from the same pool as that of file handles.  That is "
"what allows sockets to be treated the same way as files."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:250
msgid ""
"The `domain` argument tells the system what _protocol family_ you want it to "
"use.  Many of them exist, some are vendor specific, others are very common.  "
"They are declared in [.filename]#sys/socket.h#."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:252
msgid "Use `PF_INET` for UDP, TCP and other Internet protocols (IPv4)."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:256
msgid ""
"Five values are defined for the `type` argument, again, in [.filename]#sys/"
"socket.h#.  All of them start with \"`SOCK_`\".  The most common one is "
"`SOCK_STREAM`, which tells the system you are asking for a _reliable stream "
"delivery service_ (which is TCP when used with `PF_INET`)."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:258
msgid ""
"If you asked for `SOCK_DGRAM`, you would be requesting a _connectionless "
"datagram delivery service_ (in our case, UDP)."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:260
msgid ""
"If you wanted to be in charge of the low-level protocols (such as IP), or "
"even network interfaces (e.g., the Ethernet), you would need to specify "
"`SOCK_RAW`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:263
msgid ""
"Finally, the `protocol` argument depends on the previous two arguments, and "
"is not always meaningful.  In that case, use `0` for its value."
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:265
#, no-wrap
msgid "The Unconnected Socket"
msgstr ""

#. type: delimited block = 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:269
msgid ""
"Nowhere, in the `socket` function have we specified to what other system we "
"should be connected.  Our newly created socket remains _unconnected_."
msgstr ""

#. type: delimited block = 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:272
msgid ""
"This is on purpose: To use a telephone analogy, we have just attached a "
"modem to the phone line.  We have neither told the modem to make a call, nor "
"to answer if the phone rings."
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:275
#, no-wrap
msgid "`sockaddr`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:280
msgid ""
"Various functions of the sockets family expect the address of (or pointer "
"to, to use C terminology) a small area of the memory.  The various C "
"declarations in the [.filename]#sys/socket.h# refer to it as `struct "
"sockaddr`.  This structure is declared in the same file:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:293
#, no-wrap
msgid ""
"/*\n"
" * Structure used by kernel to store most\n"
" * addresses.\n"
" */\n"
"struct sockaddr {\n"
"\tunsigned char\tsa_len;\t\t/* total length */\n"
"\tsa_family_t\tsa_family;\t/* address family */\n"
"\tchar\t\tsa_data[14];\t/* actually longer; address value */\n"
"};\n"
"#define\tSOCK_MAXADDRLEN\t255\t\t/* longest possible addresses */\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:297
msgid ""
"Please note the _vagueness_ with which the `sa_data` field is declared, just "
"as an array of `14` bytes, with the comment hinting there can be more than "
"`14` of them."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:300
msgid ""
"This vagueness is quite deliberate. Sockets is a very powerful interface.  "
"While most people perhaps think of it as nothing more than the Internet "
"interface-and most applications probably use it for that nowadays-sockets "
"can be used for just about _any_ kind of interprocess communications, of "
"which the Internet (or, more precisely, IP) is only one."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:303
msgid ""
"The [.filename]#sys/socket.h# refers to the various types of protocols "
"sockets will handle as _address families_, and lists them right before the "
"definition of `sockaddr`:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:352
#, no-wrap
msgid ""
"/*\n"
" * Address families.\n"
" */\n"
"#define\tAF_UNSPEC\t0\t\t/* unspecified */\n"
"#define\tAF_LOCAL\t1\t\t/* local to host (pipes, portals) */\n"
"#define\tAF_UNIX\t\tAF_LOCAL\t/* backward compatibility */\n"
"#define\tAF_INET\t\t2\t\t/* internetwork: UDP, TCP, etc. */\n"
"#define\tAF_IMPLINK\t3\t\t/* arpanet imp addresses */\n"
"#define\tAF_PUP\t\t4\t\t/* pup protocols: e.g. BSP */\n"
"#define\tAF_CHAOS\t5\t\t/* mit CHAOS protocols */\n"
"#define\tAF_NS\t\t6\t\t/* XEROX NS protocols */\n"
"#define\tAF_ISO\t\t7\t\t/* ISO protocols */\n"
"#define\tAF_OSI\t\tAF_ISO\n"
"#define\tAF_ECMA\t\t8\t\t/* European computer manufacturers */\n"
"#define\tAF_DATAKIT\t9\t\t/* datakit protocols */\n"
"#define\tAF_CCITT\t10\t\t/* CCITT protocols, X.25 etc */\n"
"#define\tAF_SNA\t\t11\t\t/* IBM SNA */\n"
"#define AF_DECnet\t12\t\t/* DECnet */\n"
"#define AF_DLI\t\t13\t\t/* DEC Direct data link interface */\n"
"#define AF_LAT\t\t14\t\t/* LAT */\n"
"#define\tAF_HYLINK\t15\t\t/* NSC Hyperchannel */\n"
"#define\tAF_APPLETALK\t16\t\t/* Apple Talk */\n"
"#define\tAF_ROUTE\t17\t\t/* Internal Routing Protocol */\n"
"#define\tAF_LINK\t\t18\t\t/* Link layer interface */\n"
"#define\tpseudo_AF_XTP\t19\t\t/* eXpress Transfer Protocol (no AF) */\n"
"#define\tAF_COIP\t\t20\t\t/* connection-oriented IP, aka ST II */\n"
"#define\tAF_CNT\t\t21\t\t/* Computer Network Technology */\n"
"#define pseudo_AF_RTIP\t22\t\t/* Help Identify RTIP packets */\n"
"#define\tAF_IPX\t\t23\t\t/* Novell Internet Protocol */\n"
"#define\tAF_SIP\t\t24\t\t/* Simple Internet Protocol */\n"
"#define\tpseudo_AF_PIP\t25\t\t/* Help Identify PIP packets */\n"
"#define\tAF_ISDN\t\t26\t\t/* Integrated Services Digital Network*/\n"
"#define\tAF_E164\t\tAF_ISDN\t\t/* CCITT E.164 recommendation */\n"
"#define\tpseudo_AF_KEY\t27\t\t/* Internal key-management function */\n"
"#define\tAF_INET6\t28\t\t/* IPv6 */\n"
"#define\tAF_NATM\t\t29\t\t/* native ATM access */\n"
"#define\tAF_ATM\t\t30\t\t/* ATM */\n"
"#define pseudo_AF_HDRCMPLT 31\t\t/* Used by BPF to not rewrite headers\n"
"\t\t\t\t\t * in interface output routine\n"
"\t\t\t\t\t */\n"
"#define\tAF_NETGRAPH\t32\t\t/* Netgraph sockets */\n"
"#define\tAF_SLOW\t\t33\t\t/* 802.3ad slow protocol */\n"
"#define\tAF_SCLUSTER\t34\t\t/* Sitara cluster protocol */\n"
"#define\tAF_ARP\t\t35\n"
"#define\tAF_BLUETOOTH\t36\t\t/* Bluetooth sockets */\n"
"#define\tAF_MAX\t\t37\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:356
msgid "The one used for IP is AF_INET.  It is a symbol for the constant `2`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:358
msgid ""
"It is the _address family_ listed in the `sa_family` field of `sockaddr` "
"that decides how exactly the vaguely named bytes of `sa_data` will be used."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:360
msgid ""
"Specifically, whenever the _address family_ is AF_INET, we can use `struct "
"sockaddr_in` found in [.filename]#netinet/in.h#, wherever `sockaddr` is "
"expected:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:373
#, no-wrap
msgid ""
"/*\n"
" * Socket address, internet style.\n"
" */\n"
"struct sockaddr_in {\n"
"\tuint8_t\t\tsin_len;\n"
"\tsa_family_t\tsin_family;\n"
"\tin_port_t\tsin_port;\n"
"\tstruct\tin_addr sin_addr;\n"
"\tchar\tsin_zero[8];\n"
"};\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:376
msgid "We can visualize its organization this way:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:377
#, no-wrap
msgid "sockaddr_in structure"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:378
#, no-wrap
msgid "sain.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:381
msgid ""
"The three important fields are `sin_family`, which is byte 1 of the "
"structure, `sin_port`, a 16-bit value found in bytes 2 and 3, and "
"`sin_addr`, a 32-bit integer representation of the IP address, stored in "
"bytes 4-7."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:387
msgid ""
"Now, let us try to fill it out.  Let us assume we are trying to write a "
"client for the _daytime_ protocol, which simply states that its server will "
"write a text string representing the current date and time to port 13.  We "
"want to use TCP/IP, so we need to specify `AF_INET` in the address family "
"field.  `AF_INET` is defined as `2`.  Let us use the IP address of "
"`132.163.96.1`, which is the time server of US federal government "
"(`time.nist.gov`)."
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:388
#, no-wrap
msgid "Specific example of sockaddr_in"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:389
#, no-wrap
msgid "sainfill.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:392
msgid ""
"By the way the `sin_addr` field is declared as being of the `struct in_addr` "
"type, which is defined in [.filename]#netinet/in.h#:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:401
#, no-wrap
msgid ""
"/*\n"
" * Internet address (a structure for historical reasons)\n"
" */\n"
"struct in_addr {\n"
"\tin_addr_t s_addr;\n"
"};\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:404
msgid "In addition, `in_addr_t` is a 32-bit integer."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:406
msgid ""
"The `132.163.96.1` is just a convenient notation of expressing a 32-bit "
"integer by listing all of its 8-bit bytes, starting with the _most "
"significant_ one."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:410
msgid ""
"So far, we have viewed `sockaddr` as an abstraction.  Our computer does not "
"store `short` integers as a single 16-bit entity, but as a sequence of 2 "
"bytes.  Similarly, it stores 32-bit integers as a sequence of 4 bytes."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:412
msgid "Suppose we coded something like this:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:418
#, no-wrap
msgid ""
"sa.sin_family      = AF_INET;\n"
"sa.sin_port        = 13;\n"
"sa.sin_addr.s_addr = (((((132 << 8) | 163) << 8) | 96) << 8) | 1;\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:421
msgid "What would the result look like?"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:424
msgid ""
"Well, that depends, of course.  On a Pentium(R), or other x86, based "
"computer, it would look like this:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:425
#, no-wrap
msgid "sockaddr_in on an Intel system"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:426
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:472
#, no-wrap
msgid "sainlsb.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:429
msgid "On a different system, it might look like this:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:430
#, no-wrap
msgid "sockaddr_in on an MSB system"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:431
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:477
#, no-wrap
msgid "sainmsb.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:435
msgid ""
"And on a PDP it might look different yet.  But the above two are the most "
"common ways in use today."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:439
msgid ""
"Ordinarily, wanting to write portable code, programmers pretend that these "
"differences do not exist.  And they get away with it (except when they code "
"in assembly language).  Alas, you cannot get away with it that easily when "
"coding for sockets."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:441
msgid "Why?"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:443
msgid ""
"Because when communicating with another computer, you usually do not know "
"whether it stores data _most significant byte_ (MSB) or _least significant "
"byte_ (LSB) first."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:445
msgid "You might be wondering, _\"So, will sockets not handle it for me?\"_"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:447
msgid "It will not."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:450
msgid ""
"While that answer may surprise you at first, remember that the general "
"sockets interface only understands the `sa_len` and `sa_family` fields of "
"the `sockaddr` structure.  You do not have to worry about the byte order "
"there (of course, on FreeBSD `sa_family` is only 1 byte anyway, but many "
"other UNIX(R) systems do not have `sa_len` and use 2 bytes for `sa_family`, "
"and expect the data in whatever order is native to the computer)."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:453
msgid ""
"But the rest of the data is just `sa_data[14]` as far as sockets goes.  "
"Depending on the _address family_, sockets just forwards that data to its "
"destination."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:458
msgid ""
"Indeed, when we enter a port number, it is because we want the other "
"computer to know what service we are asking for.  And, when we are the "
"server, we read the port number so we know what service the other computer "
"is expecting from us.  Either way, sockets only has to forward the port "
"number as data.  It does not interpret it in any way."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:461
msgid ""
"Similarly, we enter the IP address to tell everyone on the way where to send "
"our data to.  Sockets, again, only forwards it as data."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:463
msgid ""
"That is why, we (the _programmers_, not the _sockets_) have to distinguish "
"between the byte order used by our computer and a conventional byte order to "
"send the data in to the other computer."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:465
msgid ""
"We will call the byte order our computer uses the _host byte order_, or just "
"the _host order_."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:468
msgid ""
"There is a convention of sending the multi-byte data over IP _MSB first_.  "
"This, we will refer to as the _network byte order_, or simply the _network "
"order_."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:470
msgid ""
"Now, if we compiled the above code for an Intel based computer, our _host "
"byte order_ would produce:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:471
#, no-wrap
msgid "Host byte order on an Intel system"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:475
msgid "But the _network byte order_ requires that we store the data MSB first:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:476
#, no-wrap
msgid "Network byte order"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:480
msgid ""
"Unfortunately, our _host order_ is the exact opposite of the _network order_."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:483
msgid ""
"We have several ways of dealing with it.  One would be to _reverse_ the "
"values in our code:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:489
#, no-wrap
msgid ""
"sa.sin_family      = AF_INET;\n"
"sa.sin_port        = 13 << 8;\n"
"sa.sin_addr.s_addr = (((((1 << 8) | 96) << 8) | 163) << 8) | 132;\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:494
msgid ""
"This will _trick_ our compiler into storing the data in the _network byte "
"order_.  In some cases, this is exactly the way to do it (e.g., when "
"programming in assembly language).  In most cases, however, it can cause a "
"problem."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:498
msgid ""
"Suppose, you wrote a sockets-based program in C.  You know it is going to "
"run on a Pentium(R), so you enter all your constants in reverse and force "
"them to the _network byte order_.  It works well."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:503
msgid ""
"Then, some day, your trusted old Pentium(R) becomes a rusty old Pentium(R).  "
"You replace it with a system whose _host order_ is the same as the _network "
"order_.  You need to recompile all your software.  All of your software "
"continues to perform well, except the one program you wrote."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:507
msgid ""
"You have since forgotten that you had forced all of your constants to the "
"opposite of the _host order_.  You spend some quality time tearing out your "
"hair, calling the names of all gods you ever heard of (and some you made "
"up), hitting your monitor with a nerf bat, and performing all the other "
"traditional ceremonies of trying to figure out why something that has worked "
"so well is suddenly not working at all."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:509
msgid ""
"Eventually, you figure it out, say a couple of swear words, and start "
"rewriting your code."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:512
msgid ""
"Luckily, you are not the first one to face the problem.  Someone else has "
"created the man:htons[3] and man:htonl[3] C functions to convert a `short` "
"and `long` respectively from the _host byte order_ to the _network byte "
"order_, and the man:ntohs[3] and man:ntohl[3] C functions to go the other "
"way."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:515
msgid ""
"On _MSB-first_ systems these functions do nothing.  On _LSB-first_ systems "
"they convert values to the proper order."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:517
msgid ""
"So, regardless of what system your software is compiled on, your data will "
"end up in the correct order if you use these functions."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:519
#, no-wrap
msgid "Client Functions"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:524
msgid ""
"Typically, the client initiates the connection to the server.  The client "
"knows which server it is about to call: It knows its IP address, and it "
"knows the _port_ the server resides at.  It is akin to you picking up the "
"phone and dialing the number (the _address_), then, after someone answers, "
"asking for the person in charge of wingdings (the _port_)."
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:526
#, no-wrap
msgid "`connect`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:529
msgid ""
"Once a client has created a socket, it needs to connect it to a specific "
"port on a remote system. It uses man:connect[2]:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:533
#, no-wrap
msgid "int connect(int s, const struct sockaddr *name, socklen_t namelen);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:538
msgid ""
"The `s` argument is the socket, i.e., the value returned by the `socket` "
"function.  The `name` is a pointer to `sockaddr`, the structure we have "
"talked about extensively.  Finally, `namelen` informs the system how many "
"bytes are in our `sockaddr` structure."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:541
msgid ""
"If `connect` is successful, it returns `0`.  Otherwise it returns `-1` and "
"stores the error code in `errno`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:545
msgid ""
"There are many reasons why `connect` may fail.  For example, with an attempt "
"to an Internet connection, the IP address may not exist, or it may be down, "
"or just too busy, or it may not have a server listening at the specified "
"port.  Or it may outright _refuse_ any request for specific code."
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:547
#, no-wrap
msgid "Our First Client"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:550
msgid ""
"We now know enough to write a very simple client, one that will get current "
"time from `132.163.96.1` and print it to [.filename]#stdout#."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:564
#, no-wrap
msgid ""
"/*\n"
" * daytime.c\n"
" *\n"
" * Programmed by G. Adam Stanislav\n"
" */\n"
"#include <stdio.h>\n"
"#include <string.h>\n"
"#include <sys/types.h>\n"
"#include <sys/socket.h>\n"
"#include <netinet/in.h>\n"
"#include <unistd.h>\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:569
#, no-wrap
msgid ""
"int main() {\n"
"  int s, bytes;\n"
"  struct sockaddr_in sa;\n"
"  char buffer[BUFSIZ+1];\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:574
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:993
#, no-wrap
msgid ""
"  if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {\n"
"    perror(\"socket\");\n"
"    return 1;\n"
"  }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:576
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:995
#, no-wrap
msgid "  memset(&sa, '\\0', sizeof(sa));\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:585
#, no-wrap
msgid ""
"  sa.sin_family = AF_INET;\n"
"  sa.sin_port = htons(13);\n"
"  sa.sin_addr.s_addr = htonl((((((132 << 8) | 163) << 8) | 96) << 8) | 1);\n"
"  if (connect(s, (struct sockaddr *)&sa, sizeof sa) < 0) {\n"
"    perror(\"connect\");\n"
"    close(s);\n"
"    return 2;\n"
"  }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:588
#, no-wrap
msgid ""
"  while ((bytes = read(s, buffer, BUFSIZ)) > 0)\n"
"    write(1, buffer, bytes);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:592
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1019
#, no-wrap
msgid ""
"  close(s);\n"
"  return 0;\n"
"}\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:595
msgid ""
"Go ahead, enter it in your editor, save it as [.filename]#daytime.c#, then "
"compile and run it:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:600
#, no-wrap
msgid ""
"% cc -O3 -o daytime daytime.c\n"
"% ./daytime\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:603
#, no-wrap
msgid ""
"52079 01-06-19 02:29:25 50 0 1 543.9 UTC(NIST) *\n"
"%\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:607
msgid ""
"In this case, the date was June 19, 2001, the time was 02:29:25 UTC.  "
"Naturally, your results will vary."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:609
#, no-wrap
msgid "Server Functions"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:615
msgid ""
"The typical server does not initiate the connection.  Instead, it waits for "
"a client to call it and request services.  It does not know when the client "
"will call, nor how many clients will call.  It may be just sitting there, "
"waiting patiently, one moment, The next moment, it can find itself swamped "
"with requests from a number of clients, all calling in at the same time."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:617
msgid "The sockets interface offers three basic functions to handle this."
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:619
#, no-wrap
msgid "`bind`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:622
msgid ""
"Ports are like extensions to a phone line: After you dial a number, you dial "
"the extension to get to a specific person or department."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:626
msgid ""
"There are 65535 IP ports, but a server usually processes requests that come "
"in on only one of them.  It is like telling the phone room operator that we "
"are now at work and available to answer the phone at a specific extension.  "
"We use man:bind[2] to tell sockets which port we want to serve."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:630
#, no-wrap
msgid "int bind(int s, const struct sockaddr *addr, socklen_t addrlen);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:635
msgid ""
"Beside specifying the port in `addr`, the server may include its IP "
"address.  However, it can just use the symbolic constant INADDR_ANY to "
"indicate it will serve all requests to the specified port regardless of what "
"its IP address is.  This symbol, along with several similar ones, is "
"declared in [.filename]#netinet/in.h#"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:639
#, no-wrap
msgid "#define\tINADDR_ANY\t\t(u_int32_t)0x00000000\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:644
msgid ""
"Suppose we were writing a server for the _daytime_ protocol over TCP/IP.  "
"Recall that it uses port 13.  Our `sockaddr_in` structure would look like "
"this:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:645
#, no-wrap
msgid "Example Server sockaddr_in"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:646
#, no-wrap
msgid "sainserv.png"
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:649
#, no-wrap
msgid "`listen`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:653
msgid ""
"To continue our office phone analogy, after you have told the phone central "
"operator what extension you will be at, you now walk into your office, and "
"make sure your own phone is plugged in and the ringer is turned on.  Plus, "
"you make sure your call waiting is activated, so you can hear the phone ring "
"even while you are talking to someone."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:655
msgid "The server ensures all of that with the man:listen[2] function."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:659
#, no-wrap
msgid "int listen(int s, int backlog);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:663
msgid ""
"In here, the `backlog` variable tells sockets how many incoming requests to "
"accept while you are busy processing the last request.  In other words, it "
"determines the maximum size of the queue of pending connections."
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:665
#, no-wrap
msgid "`accept`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:670
msgid ""
"After you hear the phone ringing, you accept the call by answering the "
"call.  You have now established a connection with your client.  This "
"connection remains active until either you or your client hang up."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:672
msgid "The server accepts the connection by using the man:accept[2] function."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:676
#, no-wrap
msgid "int accept(int s, struct sockaddr *addr, socklen_t *addrlen);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:680
msgid ""
"Note that this time `addrlen` is a pointer.  This is necessary because in "
"this case it is the socket that fills out `addr`, the `sockaddr_in` "
"structure."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:684
msgid ""
"The return value is an integer.  Indeed, the `accept` returns a _new "
"socket_.  You will use this new socket to communicate with the client."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:686
msgid ""
"What happens to the old socket? It continues to listen for more requests "
"(remember the `backlog` variable we passed to `listen`?) until we `close` it."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:690
msgid ""
"Now, the new socket is meant only for communications.  It is fully "
"connected.  We cannot pass it to `listen` again, trying to accept additional "
"connections."
msgstr ""

#. type: Title =====
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:692
#, no-wrap
msgid "Our First Server"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:696
msgid ""
"Our first server will be somewhat more complex than our first client was: "
"Not only do we have more sockets functions to use, but we need to write it "
"as a daemon."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:699
msgid ""
"This is best achieved by creating a _child process_ after binding the port.  "
"The main process then exits and returns control to the shell (or whatever "
"program invoked it)."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:701
msgid ""
"The child calls `listen`, then starts an endless loop, which accepts a "
"connection, serves it, and eventually closes its socket."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:717
#, no-wrap
msgid ""
"/*\n"
" * daytimed - a port 13 server\n"
" *\n"
" * Programmed by G. Adam Stanislav\n"
" * June 19, 2001\n"
" */\n"
"#include <stdio.h>\n"
"#include <string.h>\n"
"#include <time.h>\n"
"#include <unistd.h>\n"
"#include <sys/types.h>\n"
"#include <sys/socket.h>\n"
"#include <netinet/in.h>\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:719
#, no-wrap
msgid "#define BACKLOG 4\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:727
#, no-wrap
msgid ""
"int main() {\n"
"    int s, c;\n"
"    socklen_t b;\n"
"    struct sockaddr_in sa;\n"
"    time_t t;\n"
"    struct tm *tm;\n"
"    FILE *client;\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:732
#, no-wrap
msgid ""
"    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {\n"
"        perror(\"socket\");\n"
"        return 1;\n"
"    }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:734
#, no-wrap
msgid "    memset(&sa, '\\0', sizeof(sa));\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:737
#, no-wrap
msgid ""
"    sa.sin_family = AF_INET;\n"
"    sa.sin_port   = htons(13);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:740
#, no-wrap
msgid ""
"    if (INADDR_ANY)\n"
"        sa.sin_addr.s_addr = htonl(INADDR_ANY);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:745
#, no-wrap
msgid ""
"    if (bind(s, (struct sockaddr *)&sa, sizeof sa) < 0) {\n"
"        perror(\"bind\");\n"
"        return 2;\n"
"    }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:756
#, no-wrap
msgid ""
"    switch (fork()) {\n"
"        case -1:\n"
"            perror(\"fork\");\n"
"            return 3;\n"
"        default:\n"
"            close(s);\n"
"            return 0;\n"
"        case 0:\n"
"            break;\n"
"    }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:758
#, no-wrap
msgid "    listen(s, BACKLOG);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:761
#, no-wrap
msgid ""
"    for (;;) {\n"
"        b = sizeof sa;\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:766
#, no-wrap
msgid ""
"        if ((c = accept(s, (struct sockaddr *)&sa, &b)) < 0) {\n"
"            perror(\"daytimed accept\");\n"
"            return 4;\n"
"        }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:771
#, no-wrap
msgid ""
"        if ((client = fdopen(c, \"w\")) == NULL) {\n"
"            perror(\"daytimed fdopen\");\n"
"            return 5;\n"
"        }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:776
#, no-wrap
msgid ""
"        if ((t = time(NULL)) < 0) {\n"
"            perror(\"daytimed time\");\n"
"            return 6;\n"
"        }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:785
#, no-wrap
msgid ""
"        tm = gmtime(&t);\n"
"        fprintf(client, \"%.4i-%.2i-%.2iT%.2i:%.2i:%.2iZ\\n\",\n"
"            tm->tm_year + 1900,\n"
"            tm->tm_mon + 1,\n"
"            tm->tm_mday,\n"
"            tm->tm_hour,\n"
"            tm->tm_min,\n"
"            tm->tm_sec);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:789
#, no-wrap
msgid ""
"        fclose(client);\n"
"    }\n"
"}\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:794
msgid ""
"We start by creating a socket.  Then we fill out the `sockaddr_in` structure "
"in `sa`.  Note the conditional use of INADDR_ANY:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:799
#, no-wrap
msgid ""
"if (INADDR_ANY)\n"
"        sa.sin_addr.s_addr = htonl(INADDR_ANY);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:806
msgid ""
"Its value is `0`.  Since we have just used `memset` to set zeroes on the "
"entire structure, it would be redundant to set it to `0` again.  But if we "
"port our code to some other system where INADDR_ANY is perhaps not a zero, "
"we need to assign it to `sa.sin_addr.s_addr`.  Most modern C compilers are "
"clever enough to notice that INADDR_ANY is a constant.  As long as it is a "
"zero, they will optimize the entire conditional statement out of the code."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:810
msgid ""
"After we have called `bind` successfully, we are ready to become a _daemon_: "
"We use `fork` to create a child process.  In both, the parent and the child, "
"the `s` variable is our socket.  The parent process will not need it, so it "
"calls `close`, then it returns `0` to inform its own parent it had "
"terminated successfully."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:815
msgid ""
"Meanwhile, the child process continues working in the background.  It calls "
"`listen` and sets its backlog to `4`.  It does not need a large value here "
"because _daytime_ is not a protocol many clients request all the time, and "
"because it can process each request instantly anyway."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:817
msgid ""
"Finally, the daemon starts an endless loop, which performs the following "
"steps:"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:820
msgid ""
"Call `accept`. It waits here until a client contacts it. At that point, it "
"receives a new socket, `c`, which it can use to communicate with this "
"particular client."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:821
msgid ""
"It uses the C function `fdopen` to turn the socket from a low-level _file "
"descriptor_ to a C-style `FILE` pointer. This will allow the use of "
"`fprintf` later on."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:822
msgid ""
"It checks the time, and prints it in the _ISO 8601_ format to the `client` "
"\"file\". It then uses `fclose` to close the file. That will automatically "
"close the socket as well."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:824
msgid "We can _generalize_ this, and use it as a model for many other servers:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:825
#, no-wrap
msgid "Sequential Server"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:826
#, no-wrap
msgid "serv.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:832
msgid ""
"This flowchart is good for _sequential servers_, i.e., servers that can "
"serve one client at a time, just as we were able to with our _daytime_ "
"server.  This is only possible whenever there is no real \"conversation\" "
"going on between the client and the server: As soon as the server detects a "
"connection to the client, it sends out some data and closes the connection.  "
"The entire operation may take nanoseconds, and it is finished."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:835
msgid ""
"The advantage of this flowchart is that, except for the brief moment after "
"the parent ``fork``s and before it exits, there is always only one _process_ "
"active: Our server does not take up much memory and other system resources."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:839
msgid ""
"Note that we have added _initialize daemon_ in our flowchart.  We did not "
"need to initialize our own daemon, but this is a good place in the flow of "
"the program to set up any `signal` handlers, open any files we may need, etc."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:843
msgid ""
"Just about everything in the flow chart can be used literally on many "
"different servers.  The _serve_ entry is the exception.  We think of it as a "
"_\"black box\"_, i.e., something you design specifically for your own "
"server, and just \"plug it into the rest.\""
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:849
msgid ""
"Not all protocols are that simple.  Many receive a request from the client, "
"reply to it, then receive another request from the same client.  As a "
"result, they do not know in advance how long they will be serving the "
"client.  Such servers usually start a new process for each client.  While "
"the new process is serving its client, the daemon can continue listening for "
"more connections."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:852
msgid ""
"Now, go ahead, save the above source code as [.filename]#daytimed.c# (it is "
"customary to end the names of daemons with the letter `d`).  After you have "
"compiled it, try running it:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:858
#, no-wrap
msgid ""
"% ./daytimed\n"
"bind: Permission denied\n"
"%\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:862
msgid ""
"What happened here? As you will recall, the _daytime_ protocol uses port "
"13.  But all ports below 1024 are reserved to the superuser (otherwise, "
"anyone could start a daemon pretending to serve a commonly used port, while "
"causing a security breach)."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:864
msgid "Try again, this time as the superuser:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:869
#, no-wrap
msgid ""
"# ./daytimed\n"
"#\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:872
msgid "What... Nothing? Let us try again:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:876
#, no-wrap
msgid "# ./daytimed\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:879
#, no-wrap
msgid ""
"bind: Address already in use\n"
"#\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:884
msgid ""
"Every port can only be bound by one program at a time.  Our first attempt "
"was indeed successful: It started the child daemon and returned quietly.  It "
"is still running and will continue to run until you either kill it, or any "
"of its system calls fail, or you reboot the system."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:887
msgid ""
"Fine, we know it is running in the background.  But is it working? How do we "
"know it is a proper _daytime_ server? Simple:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:891
#, no-wrap
msgid "% telnet localhost 13\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:900
#, no-wrap
msgid ""
"Trying ::1...\n"
"telnet: connect to address ::1: Connection refused\n"
"Trying 127.0.0.1...\n"
"Connected to localhost.\n"
"Escape character is '^]'.\n"
"2001-06-19T21:04:42Z\n"
"Connection closed by foreign host.\n"
"%\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:905
msgid ""
"telnet tried the new IPv6, and failed.  It retried with IPv4 and succeeded.  "
"The daemon works."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:908
msgid ""
"If you have access to another UNIX(R) system via telnet, you can use it to "
"test accessing the server remotely.  My computer does not have a static IP "
"address, so this is what I did:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:912
#, no-wrap
msgid "% who\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:916
#, no-wrap
msgid ""
"whizkid          ttyp0   Jun 19 16:59   (216.127.220.143)\n"
"xxx              ttyp1   Jun 19 16:06   (xx.xx.xx.xx)\n"
"% telnet 216.127.220.143 13\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:923
#, no-wrap
msgid ""
"Trying 216.127.220.143...\n"
"Connected to r47.bfm.org.\n"
"Escape character is '^]'.\n"
"2001-06-19T21:31:11Z\n"
"Connection closed by foreign host.\n"
"%\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:926
msgid "Again, it worked. Will it work using the domain name?"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:930
#, no-wrap
msgid "% telnet r47.bfm.org 13\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:937
#, no-wrap
msgid ""
"Trying 216.127.220.143...\n"
"Connected to r47.bfm.org.\n"
"Escape character is '^]'.\n"
"2001-06-19T21:31:40Z\n"
"Connection closed by foreign host.\n"
"%\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:941
msgid ""
"By the way, telnet prints the _Connection closed by foreign host_ message "
"after our daemon has closed the socket.  This shows us that, indeed, using "
"`fclose(client);` in our code works as advertised."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:943
#, no-wrap
msgid "Helper Functions"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:949
msgid ""
"FreeBSD C library contains many helper functions for sockets programming.  "
"For example, in our sample client we hard coded the `time.nist.gov` IP "
"address.  But we do not always know the IP address.  Even if we do, our "
"software is more flexible if it allows the user to enter the IP address, or "
"even the domain name."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:951
#, no-wrap
msgid "`gethostbyname`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:954
msgid ""
"While there is no way to pass the domain name directly to any of the sockets "
"functions, the FreeBSD C library comes with the man:gethostbyname[3] and "
"man:gethostbyname2[3] functions, declared in [.filename]#netdb.h#."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:959
#, no-wrap
msgid ""
"struct hostent * gethostbyname(const char *name);\n"
"struct hostent * gethostbyname2(const char *name, int af);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:963
msgid ""
"Both return a pointer to the `hostent` structure, with much information "
"about the domain.  For our purposes, the `h_addr_list[0]` field of the "
"structure points at `h_length` bytes of the correct address, already stored "
"in the _network byte order_."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:965
msgid ""
"This allows us to create a much more flexible-and much more useful-version "
"of our daytime program:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:981
#, no-wrap
msgid ""
"/*\n"
" * daytime.c\n"
" *\n"
" * Programmed by G. Adam Stanislav\n"
" * 19 June 2001\n"
" */\n"
"#include <stdio.h>\n"
"#include <string.h>\n"
"#include <unistd.h>\n"
"#include <sys/types.h>\n"
"#include <sys/socket.h>\n"
"#include <netinet/in.h>\n"
"#include <netdb.h>\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:988
#, no-wrap
msgid ""
"int main(int argc, char *argv[]) {\n"
"  int s, bytes;\n"
"  struct sockaddr_in sa;\n"
"  struct hostent *he;\n"
"  char buf[BUFSIZ+1];\n"
"  char *host;\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:998
#, no-wrap
msgid ""
"  sa.sin_family = AF_INET;\n"
"  sa.sin_port = htons(13);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1000
#, no-wrap
msgid "  host = (argc > 1) ? argv[1] : \"time.nist.gov\";\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1005
#, no-wrap
msgid ""
"  if ((he = gethostbyname(host)) == NULL) {\n"
"    herror(host);\n"
"    return 2;\n"
"  }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1007
#, no-wrap
msgid "  memcpy(&sa.sin_addr, he->h_addr_list[0], he->h_length);\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1012
#, no-wrap
msgid ""
"  if (connect(s, (struct sockaddr *)&sa, sizeof sa) < 0) {\n"
"    perror(\"connect\");\n"
"    return 3;\n"
"  }\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1015
#, no-wrap
msgid ""
"  while ((bytes = read(s, buf, BUFSIZ)) > 0)\n"
"    write(1, buf, bytes);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1025
msgid ""
"We now can type a domain name (or an IP address, it works both ways) on the "
"command line, and the program will try to connect to its _daytime_ server.  "
"Otherwise, it will still default to `time.nist.gov`.  However, even in this "
"case we will use `gethostbyname` rather than hard coding `132.163.96.1`.  "
"That way, even if its IP address changes in the future, we will still find "
"it."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1029
msgid ""
"Since it takes virtually no time to get the time from your local server, you "
"could run daytime twice in a row: First to get the time from "
"`time.nist.gov`, the second time from your own system.  You can then compare "
"the results and see how exact your system clock is:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1033
#, no-wrap
msgid "% daytime ; daytime localhost\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1037
#, no-wrap
msgid ""
"52080 01-06-20 04:02:33 50 0 0 390.2 UTC(NIST) *\n"
"2001-06-20T04:02:35Z\n"
"%\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1040
msgid "As you can see, my system was two seconds ahead of the NIST time."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1042
#, no-wrap
msgid "`getservbyname`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1046
msgid ""
"Sometimes you may not be sure what port a certain service uses.  The "
"man:getservbyname[3] function, also declared in [.filename]#netdb.h# comes "
"in very handy in those cases:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1050
#, no-wrap
msgid "struct servent * getservbyname(const char *name, const char *proto);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1053
msgid ""
"The `servent` structure contains the `s_port`, which contains the proper "
"port, already in _network byte order_."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1055
msgid ""
"Had we not known the correct port for the _daytime_ service, we could have "
"found it this way:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1065
#, no-wrap
msgid ""
"struct servent *se;\n"
"  ...\n"
"  if ((se = getservbyname(\"daytime\", \"tcp\")) == NULL {\n"
"    fprintf(stderr, \"Cannot determine which port to use.\\n\");\n"
"    return 7;\n"
"  }\n"
"  sa.sin_port = se->s_port;\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1072
msgid ""
"You usually do know the port.  But if you are developing a new protocol, you "
"may be testing it on an unofficial port.  Some day, you will register the "
"protocol and its port (if nowhere else, at least in your [.filename]#/etc/"
"services#, which is where `getservbyname` looks).  Instead of returning an "
"error in the above code, you just use the temporary port number.  Once you "
"have listed the protocol in [.filename]#/etc/services#, your software will "
"find its port without you having to rewrite the code."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1074
#, no-wrap
msgid "Concurrent Servers"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1078
msgid ""
"Unlike a sequential server, a _concurrent server_ has to be able to serve "
"more than one client at a time.  For example, a _chat server_ may be serving "
"a specific client for hours-it cannot wait till it stops serving a client "
"before it serves the next one."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1080
msgid "This requires a significant change in our flowchart:"
msgstr ""

#. type: Block title
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1081
#, no-wrap
msgid "Concurrent Server"
msgstr ""

#. type: Target for macro image
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1082
#, no-wrap
msgid "serv2.png"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1086
msgid ""
"We moved the _serve_ from the _daemon process_ to its own _server process_.  "
"However, because each child process inherits all open files (and a socket is "
"treated just like a file), the new process inherits not only the _\"accepted "
"handle,\"_ i.e., the socket returned by the `accept` call, but also the _top "
"socket_, i.e., the one opened by the top process right at the beginning."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1089
msgid ""
"However, the _server process_ does not need this socket and should `close` "
"it immediately.  Similarly, the _daemon process_ no longer needs the "
"_accepted socket_, and not only should, but _must_ `close` it-otherwise, it "
"will run out of available _file descriptors_ sooner or later."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1092
msgid ""
"After the _server process_ is done serving, it should close the _accepted "
"socket_.  Instead of returning to `accept`, it now exits."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1099
msgid ""
"Under UNIX(R), a process does not really _exit_.  Instead, it _returns_ to "
"its parent.  Typically, a parent process ``wait``s for its child process, "
"and obtains a return value.  However, our _daemon process_ cannot simply "
"stop and wait.  That would defeat the whole purpose of creating additional "
"processes.  But if it never does `wait`, its children will become _zombies_-"
"no longer functional but still roaming around."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1102
msgid ""
"For that reason, the _daemon process_ needs to set _signal handlers_ in its "
"_initialize daemon_ phase.  At least a SIGCHLD signal has to be processed, "
"so the daemon can remove the zombie return values from the system and "
"release the system resources they are taking up."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1105
msgid ""
"That is why our flowchart now contains a _process signals_ box, which is not "
"connected to any other box.  By the way, many servers also process SIGHUP, "
"and typically interpret as the signal from the superuser that they should "
"reread their configuration files.  This allows us to change settings without "
"having to kill and restart these servers."
msgstr ""