Source string Read only

(itstool) path: sect4/para
217/2170
Context English State
It is the <emphasis>address family</emphasis> listed in the <varname>sa_family</varname> field of <varname>sockaddr</varname> that decides how exactly the vaguely named bytes of <varname>sa_data</varname> will be used.
Specifically, whenever the <emphasis>address family</emphasis> is <symbol>AF_INET</symbol>, we can use <varname>struct sockaddr_in</varname> found in <filename>netinet/in.h</filename>, wherever <varname>sockaddr</varname> is expected:
/*
* Socket address, internet style.
*/
struct sockaddr_in {
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
We can visualize its organization this way:
_ external ref='sockets/sain' md5='__failed__'
0 1 2 3
+--------+--------+-----------------+
0 | 0 | Family | Port |
+--------+--------+-----------------+
4 | IP Address |
+-----------------------------------+
8 | 0 |
+-----------------------------------+
12 | 0 |
+-----------------------------------+
<imageobject> <imagedata fileref="sockets/sain"/> </imageobject> <textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>sockaddr_in</phrase> </textobject>
The three important fields are <varname>sin_family</varname>, which is byte 1 of the structure, <varname>sin_port</varname>, a 16-bit value found in bytes 2 and 3, and <varname>sin_addr</varname>, a 32-bit integer representation of the <acronym>IP</acronym> address, stored in bytes 4-7.
Now, let us try to fill it out. Let us assume we are trying to write a client for the <emphasis>daytime</emphasis> 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 <acronym>TCP/IP</acronym>, so we need to specify <constant>AF_INET</constant> in the address family field. <constant>AF_INET</constant> is defined as <constant>2</constant>. Let us use the <acronym>IP</acronym> address of <systemitem class="ipaddress">192.43.244.18</systemitem>, which is the time server of US federal government (<systemitem class="fqdomainname">time.nist.gov</systemitem>).
_ external ref='sockets/sainfill' md5='__failed__'
0 1 2 3
+--------+--------+-----------------+
0 | 0 | 2 | 13 |
+-----------------+-----------------+
4 | 192.43.244.18 |
+-----------------------------------+
8 | 0 |
+-----------------------------------+
12 | 0 |
+-----------------------------------+
<imageobject> <imagedata fileref="sockets/sainfill"/> </imageobject> <textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>Specific example of sockaddr_in</phrase> </textobject>
By the way the <varname>sin_addr</varname> field is declared as being of the <varname>struct in_addr</varname> type, which is defined in <filename>netinet/in.h</filename>:
/*
* Internet address (a structure for historical reasons)
*/
struct in_addr {
in_addr_t s_addr;
};
In addition, <varname>in_addr_t</varname> is a 32-bit integer.
The <systemitem class="ipaddress">192.43.244.18</systemitem> is just a convenient notation of expressing a 32-bit integer by listing all of its 8-bit bytes, starting with the <emphasis>most significant</emphasis> one.
So far, we have viewed <varname>sockaddr</varname> as an abstraction. Our computer does not store <varname>short</varname> 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.
Suppose we coded something like this:
sa.sin_family = AF_INET;
sa.sin_port = 13;
sa.sin_addr.s_addr = (((((192 &lt;&lt; 8) | 43) &lt;&lt; 8) | 244) &lt;&lt; 8) | 18;
What would the result look like?
Well, that depends, of course. On a <trademark class="registered">Pentium</trademark>, or other x86, based computer, it would look like this:
_ external ref='sockets/sainlsb' md5='__failed__'
0 1 2 3
+--------+--------+--------+--------+
0 | 0 | 2 | 13 | 0 |
+--------+--------+--------+--------+
4 | 18 | 244 | 43 | 192 |
+-----------------------------------+
8 | 0 |
+-----------------------------------+
12 | 0 |
+-----------------------------------+
<imageobject> <imagedata fileref="sockets/sainlsb"/> </imageobject> <textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>sockaddr_in on an Intel system</phrase> </textobject>
On a different system, it might look like this:
_ external ref='sockets/sainmsb' md5='__failed__'
0 1 2 3
+--------+--------+--------+--------+
0 | 0 | 2 | 0 | 13 |
+--------+--------+--------+--------+
4 | 192 | 43 | 244 | 18 |
+-----------------------------------+
8 | 0 |
+-----------------------------------+
12 | 0 |
+-----------------------------------+
<imageobject> <imagedata fileref="sockets/sainmsb"/> </imageobject> <textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>sockaddr_in on an MSB system</phrase> </textobject>
And on a PDP it might look different yet. But the above two are the most common ways in use today.
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.
Why?

Loading…

No matching activity found.

Browse all component changes

Glossary

English English
No related strings found in the glossary.

Source information

Source string comment
(itstool) path: sect4/para
Flags
read-only
Source string location
book.translate.xml:5536
String age
a year ago
Source string age
a year ago
Translation file
books/developers-handbook.pot, string 918