1778 lines
No EOL
147 KiB
HTML
1778 lines
No EOL
147 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
<html lang="en">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
||
<title>4.4. The Socket Interface — Computer Systems Fundamentals</title>
|
||
|
||
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
|
||
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
|
||
|
||
<style>
|
||
.underline { text-decoration: underline; }
|
||
</style>
|
||
|
||
<script type="text/javascript">
|
||
var DOCUMENTATION_OPTIONS = {
|
||
URL_ROOT: './',
|
||
VERSION: '0.4.1',
|
||
COLLAPSE_INDEX: false,
|
||
FILE_SUFFIX: '.html',
|
||
HAS_SOURCE: true
|
||
};
|
||
</script>
|
||
|
||
<script type="text/x-mathjax-config">
|
||
MathJax.Hub.Config({
|
||
tex2jax: {
|
||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||
processEscapes: true
|
||
},
|
||
"HTML-CSS": {
|
||
scale: "80"
|
||
}
|
||
});
|
||
</script>
|
||
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
|
||
<link rel="next" title="5. TCP Socket Programming: HTTP" href="TCPSockets.html" />
|
||
<link rel="prev" title="3. Network Applications and Protocols" href="NetApps.html" />
|
||
|
||
</head><body>
|
||
|
||
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
|
||
|
||
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
|
||
<!-- Show a navbar toggler on mobile -->
|
||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
|
||
<span class="navbar-toggler-icon"></span>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="defaultNavbars">
|
||
<ul class="navbar-nav mr-auto">
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle jmu-gold rounded" href="Sockets.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
|
||
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
|
||
<a class="dropdown-item" tabindex="-1" href="Sockets.html#"><b>Chapter 1</b></a>
|
||
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
||
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
||
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
||
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
||
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
||
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
||
<a class="dropdown-item" href="StateModelImplementation.html"> 1.7. Extended Example: State Model Implementation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
|
||
<a class="dropdown-item" href="ProcessesOverview.html"> 2.1. Processes and OS Basics</a>
|
||
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
||
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
||
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
||
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
||
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
||
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
||
<a class="dropdown-item" href="Extended2Processes.html"> 2.8. Extended Example: Listing Files with Processes</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
|
||
<a class="dropdown-item" href="IPCOverview.html"> 3.1. Concurrency with IPC</a>
|
||
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
||
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
||
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
||
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
||
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
||
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
||
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
||
<a class="dropdown-item" href="Extended3Bash.html"> 3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
|
||
<a class="dropdown-item" href="SocketsOverview.html"> 4.1. Networked Concurrency</a>
|
||
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
||
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
||
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
||
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
||
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
||
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
||
<a class="dropdown-item" href="Extended4CGI.html"> 4.8. Extended Example: CGI Web Server</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
|
||
<a class="dropdown-item" href="InternetOverview.html"> 5.1. The Internet and Connectivity</a>
|
||
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
||
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
||
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
||
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
||
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
||
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
||
<a class="dropdown-item" href="Extended5DNS.html"> 5.8. Extended Example: DNS client</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
|
||
<a class="dropdown-item" href="ThreadsOverview.html"> 6.1. Concurrency with Multithreading</a>
|
||
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
||
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
||
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
||
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
||
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
||
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
||
<a class="dropdown-item" href="Extended6Primes.html"> 6.8. Extended Example: Concurrent Prime Number Search</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
|
||
<a class="dropdown-item" href="SynchOverview.html"> 7.1. Synchronization Primitives</a>
|
||
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
||
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
||
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
||
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
||
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
||
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
||
<a class="dropdown-item" href="Extended7Events.html"> 7.8. Extended Example: Event Log File</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
|
||
<a class="dropdown-item" href="SynchProblemsOverview.html"> 8.1. Synchronization Patterns and Problems</a>
|
||
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
||
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
||
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
||
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
||
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
||
<a class="dropdown-item" href="Extended8ModExp.html"> 8.7. Extended Example: Parallel Modular Exponentiation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
|
||
<a class="dropdown-item" href="ParallelDistributedOverview.html"> 9.1. Parallel and Distributed Systems</a>
|
||
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
||
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
||
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
||
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
||
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
||
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
||
<a class="dropdown-item" href="Extended9Blockchain.html"> 9.8. Extended Example: Blockchain Proof-of-Work</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Appendix A</b></a>
|
||
<a class="dropdown-item" href="CLangOverview.html"> A.1. C Language Reintroduction</a>
|
||
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
||
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
||
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
||
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
||
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
||
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
||
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
||
<a class="dropdown-item" href="Files.html"> A.9. Files</a>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/Sockets.rst"
|
||
target="_blank" rel="nofollow">Show Source</a></li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
|
||
<div class="container center">
|
||
«  <a id="prevmod" href="NetApps.html">4.3. Network Applications and Protocols</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod" href="TCPSockets.html">4.5. TCP Socket Programming: HTTP</a>  »
|
||
|
||
</div>
|
||
<br />
|
||
|
||
|
||
|
||
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
|
||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/config.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "Sockets";ODSA.SETTINGS.MODULE_LONG_NAME = "The Socket Interface";ODSA.SETTINGS.MODULE_CHAPTER = "Networked Concurrency"; ODSA.SETTINGS.BUILD_DATE = "2021-06-22 13:14:03"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="the-socket-interface">
|
||
<h1>4.4. The Socket Interface<a class="headerlink" href="Sockets.html#the-socket-interface" title="Permalink to this headline">¶</a></h1>
|
||
<p>The <a class="reference internal" href="Glossary.html#term-socket"><span class="xref std std-term">socket</span></a> interface in C provides a mechanism for setting up a communication channel to
|
||
another host system. For both clients and servers, the initial function call is the same. Processes
|
||
call <code class="docutils literal notranslate"><span class="pre">socket()</span></code> to request a new socket instance from the OS. As with other forms of IPC such as
|
||
pipes, sockets are treated as files, so the process receives a file descriptor from the return
|
||
value. If the socket creation failed, the OS returns a negative value.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <sys/socket.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">socket</span> <span class="pre">(int</span> <span class="pre">domain,</span> <span class="pre">int</span> <span class="pre">type,</span> <span class="pre">int</span> <span class="pre">protocol);</span></code></dt>
|
||
<dd>Create a socket instance.</dd>
|
||
</dl>
|
||
</div>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">domain</span></code> field is used to declare the intended scope of routing needed; different values here
|
||
indicate whether the socket will be used for IPv4, IPv6, or local communication. The <code class="docutils literal notranslate"><span class="pre">type</span></code> field
|
||
determines whether the socket will read and write data as a byte stream, fixed-size messages, or as
|
||
unprocessed (raw) data. The <code class="docutils literal notranslate"><span class="pre">protocol</span></code> field is typically unused and set to 0; one exception
|
||
occurs when the client is acting as a <a class="reference internal" href="Glossary.html#term-packet-sniffer"><span class="xref std std-term">packet sniffer</span></a>, an application for capturing and
|
||
examining packets sent by other processes on a host or network. These applications use <a class="reference internal" href="Glossary.html#term-raw-socket"><span class="xref std std-term">raw
|
||
sockets</span></a>, as described below. For all three fields, the socket header file defines
|
||
constant values that are used. <a class="reference external" href="Sockets.html#tbl4-2">Table 4.2</a> identifies several common constants.</p>
|
||
<center>
|
||
<div class="col-md-10">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="py-0 center">Field</th>
|
||
<th class="py-0 center">Constant</th>
|
||
<th class="py-0 center">Purpose</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0" rowspan="5"><code>domain</code></td>
|
||
<td class="py-0"><code>AF_INET</code></td>
|
||
<td class="py-0">Use IPv4 addresses</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>AF_INET6</code></td>
|
||
<td class="py-0">Use IPv6 addresses</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>AF_LOCAL</code></td>
|
||
<td class="py-0">Unix domain socket for IPC</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>AF_NETLINK</code></td>
|
||
<td class="py-0">Netlink socket for kernel messages</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>AF_PACKET</code></td>
|
||
<td class="py-0">Raw socket type</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0" rowspan="3"><code>type</code></td>
|
||
<td class="py-0"><code>SOCK_STREAM</code></td>
|
||
<td class="py-0">Byte-stream communication, used for TCP transport</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>SOCK_DGRAM</code></td>
|
||
<td class="py-0">Fixed-size messages, used for UDP transport</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>SOCK_RAW</code></td>
|
||
<td class="py-0">Raw data that is not processed by transport layer</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0" rowspan="2"><code>protocol</code></td>
|
||
<td class="py-0"><code>IPPROTO_RAW</code></td>
|
||
<td class="py-0">Receive IP datagrams without transport-layer processing</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0"><code>ETH_P_ALL</code></td>
|
||
<td class="py-0">Receive Ethernet frames without network-layer processing</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="col-md-10 center">
|
||
Table 4.2: Common arguments to the <code>socket()</code> function
|
||
</div>
|
||
</center>
|
||
<br /><p>The <code class="docutils literal notranslate"><span class="pre">domain</span></code> and <code class="docutils literal notranslate"><span class="pre">type</span></code> field constants are defined in the <code class="docutils literal notranslate"><span class="pre">sys/socket.h</span></code> header file. The
|
||
<code class="docutils literal notranslate"><span class="pre">domain</span></code> fields listed here have another form that replaces the <code class="docutils literal notranslate"><span class="pre">AF</span></code> with <code class="docutils literal notranslate"><span class="pre">PF</span></code>. For example,
|
||
there are also <code class="docutils literal notranslate"><span class="pre">PF_INET</span></code> and <code class="docutils literal notranslate"><span class="pre">PF_PACKET</span></code> constants. The original use of this different notation
|
||
was to distinguish an <em>address family</em> (<code class="docutils literal notranslate"><span class="pre">AF</span></code>) from a <em>protocol family</em> (<code class="docutils literal notranslate"><span class="pre">PF</span></code>). In practice,
|
||
these values tend to be identical, with the <code class="docutils literal notranslate"><span class="pre">AF</span></code> form more commonly used. For the <code class="docutils literal notranslate"><span class="pre">protocol</span></code>
|
||
field, the <code class="docutils literal notranslate"><span class="pre">IPPROTO_RAW</span></code> and similar <code class="docutils literal notranslate"><span class="pre">IPPROTO_*</span></code> constants are defined in <code class="docutils literal notranslate"><span class="pre">netinet/in.h</span></code>. The
|
||
<code class="docutils literal notranslate"><span class="pre">ETH_P_ALL</span></code> and similar constants are stored in <code class="docutils literal notranslate"><span class="pre">linux/if_ether.h</span></code> on Linux systems; other
|
||
systems do not have these specific values.</p>
|
||
<p>Only certain combinations of these arguments make sense. For instance, a raw socket created with the
|
||
domain <code class="docutils literal notranslate"><span class="pre">AF_PACKET</span></code> would use the <code class="docutils literal notranslate"><span class="pre">SOCK_RAW</span></code> type; a raw socket would not be set up to use the
|
||
<code class="docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code> type, which is commonly used for the stream-oriented TCP transport-layer protocol.
|
||
Similarly, a socket created for IPv6 communication (<code class="docutils literal notranslate"><span class="pre">AF_INET6</span></code>) would not use the <code class="docutils literal notranslate"><span class="pre">SOCK_RAW</span></code>
|
||
type, which would deliver the IP datagram payload directly to the process without the
|
||
transport-layer processing; the process would then receive the full payload, including the TCP or
|
||
UDP header fields. <a class="reference external" href="Sockets.html#cl4-1">Code Listing 4.1</a> illustrates several common combinations of socket arguments.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-1"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.1:</span>
|
||
<span class="cm"> Common argument types for various sockets</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Create an IPv4 socket for TCP */</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Create an IPv6 socket for TCP */</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">AF_INET6</span><span class="p">,</span> <span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Create an IPv4 socket for UDP */</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">SOCK_DGRAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Create an IPv6 socket for UDP */</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">AF_INET6</span><span class="p">,</span> <span class="n">SOCK_DGRAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Create a raw socket for sniffing unprocessed Ethernet frames */</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">AF_PACKET</span><span class="p">,</span> <span class="n">SOCK_RAW</span><span class="p">,</span> <span class="n">htons</span> <span class="p">(</span><span class="n">ETH_P_ALL</span><span class="p">));</span>
|
||
|
||
<span class="cm">/* htons is explained below */</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Processes running on two separate hosts normally intend to exchange application-layer messages,
|
||
relying on the lower layers just as a mechanism to deliver the data. (Refer back to
|
||
<a href="FiveLayer.html#netbackbone">Figure 4.2.1</a>.) However, some processes are designed to gather information about the
|
||
network itself. One example of such a process would be a packet sniffer that captures and inspects
|
||
data sent through the network. Another example is the <code class="docutils literal notranslate"><span class="pre">traceroute</span></code> utility, which can gather
|
||
information about the routers that are encountered on the way to a target host. Both of these
|
||
applications can be used to monitor the health and performance of a network, and they also form the
|
||
basis of security tools, such as a <em>network intrusion detection systems (network IDS)</em>.</p>
|
||
<p>Applications that gather information about the network rely on the use of raw sockets, which are
|
||
sockets intended to break the layers of abstraction of the protocol stack. Using a raw socket, a
|
||
process can examine a full IP datagram or TCP packet, including their respective headers. For
|
||
instance, a raw socket with the protocol <code class="docutils literal notranslate"><span class="pre">IPPROTO_RAW</span></code> could be used to examine the TCP or UDP
|
||
headers for a packet This reveals information about the processes that sent or are intended as the
|
||
receiver of the data; however, this packet has still been processed by the Internet layer, so the IP
|
||
headers would have been removed. To examine the IP headers, the <code class="docutils literal notranslate"><span class="pre">ETH_P_ALL</span></code> protocol field is
|
||
needed.</p>
|
||
<p>Normal applications should not use raw sockets, because most of the information can be accessed in
|
||
other ways. That is, when a client connects to a server, the client would already learn that host’s
|
||
IP address and the port number associated with the server. Furthermore, using a raw socket would
|
||
require the application programmer to understand details of the transport and network protocols to
|
||
know how much data at the beginning of the message to ignore. Unless the application is specifically
|
||
designed to gather information about the network itself, raw sockets are not needed in typical use.</p>
|
||
<div class="section" id="networking-data-structures">
|
||
<h2>4.4.1. Networking Data Structures<a class="headerlink" href="Sockets.html#networking-data-structures" title="Permalink to this headline">¶</a></h2>
|
||
<p>Once the socket is created, the client and server processes use different functions to establish the
|
||
network link between their sockets. These functions rely on a common <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code> data
|
||
structure. The basic form of this structure contains two fields:</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
|
||
2
|
||
3
|
||
4
|
||
5</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* defined in sys/socket.h */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr</span> <span class="p">{</span> <span class="cm">/* generic socket address structure */</span>
|
||
<span class="n">sa_family_t</span> <span class="n">sa_family</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="n">sa_data</span><span class="p">[</span><span class="mi">14</span><span class="p">];</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>The first field, <code class="docutils literal notranslate"><span class="pre">sa_family</span></code>, is two-bytes in size and identifies the domain of the socket that is
|
||
being used. This field is set using <code class="docutils literal notranslate"><span class="pre">AF_INET</span></code>, <code class="docutils literal notranslate"><span class="pre">AF_PACKET</span></code>, and similar constants used to create
|
||
the socket. The other field, <code class="docutils literal notranslate"><span class="pre">sa_data</span></code>, is an unstructured 14-byte sequence in the generic form.
|
||
The interpretation of these bytes depends on the domain of the socket. For an IPv4 socket, the
|
||
process would create a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code> <a class="footnote-reference" href="Sockets.html#f23" id="id1">[1]</a> instead, which uses the following definition.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* defined in netinet/in.h */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="p">{</span>
|
||
<span class="n">sa_family_t</span> <span class="n">sin_family</span><span class="p">;</span>
|
||
<span class="n">in_port_t</span> <span class="n">sin_port</span><span class="p">;</span>
|
||
<span class="k">struct</span> <span class="n">in_addr</span> <span class="n">sin_addr</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="n">sin_zero</span><span class="p">[</span><span class="mi">8</span><span class="p">];</span>
|
||
<span class="p">};</span>
|
||
|
||
<span class="k">struct</span> <span class="n">in_addr</span> <span class="p">{</span>
|
||
<span class="n">in_addr_t</span> <span class="n">s_addr</span><span class="p">;</span> <span class="cm">/* in_addr_t is a typedef alias for uint32_t */</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code> and <code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code> structures are identical in size, allowing for straightforward
|
||
casting between the two. Both begin with a <code class="docutils literal notranslate"><span class="pre">sa_family_t</span></code> field to indicate the domain. As the type
|
||
is the same, both <code class="docutils literal notranslate"><span class="pre">struct</span></code>s use the same number of bytes for this information. The <code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code>
|
||
breaks the rest of the bytes into three fields. The <code class="docutils literal notranslate"><span class="pre">sin_port</span></code> is a 16-bit field to designate the
|
||
port number for the socket and the <code class="docutils literal notranslate"><span class="pre">sin_addr</span></code> contains the 32-bit IPv4 address. The <code class="docutils literal notranslate"><span class="pre">struct</span>
|
||
<span class="pre">in_addr</span></code> contains a single field, <code class="docutils literal notranslate"><span class="pre">s_addr</span></code>, which is made an alias for a <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code> by a
|
||
<code class="docutils literal notranslate"><span class="pre">typedef</span></code> elsewhere in the C library. The <code class="docutils literal notranslate"><span class="pre">sin_zero</span></code> field of <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code> is used to
|
||
pad the size of the <code class="docutils literal notranslate"><span class="pre">struct</span></code> to match the size of the original <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code>. <a class="footnote-reference" href="Sockets.html#f24" id="id2">[2]</a></p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3" id="sockexampleipv4">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 4.4.1 </p><hr class="mt-1" />
|
||
<p>To illustrate the internal structure of these address <code class="docutils literal notranslate"><span class="pre">struct</span></code>s, consider the following byte sequence:</p>
|
||
<center>
|
||
<div class="col-12">
|
||
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center jmu-dark-purple-bg" colspan="16"><code class="text-light">struct sockaddr</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="2"><code class="jmu-slate fs80 fs55">sa_family</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="14"><code class="jmu-slate">sa_data</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="6.25%"><code>02</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>50</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>5d</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>b8</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>d8</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>22</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="2"><code class="jmu-slate fs80 fs55">sin_family</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="2"><code class="jmu-slate fs65">sin_port</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="4"><code class="jmu-slate">sin_addr</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="8"><code class="jmu-slate">sin_zero</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center jmu-dark-purple-bg" colspan="16"><code class="text-light">struct sockaddr_in</code></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
</center><p>In both cases, the first two bytes denote the family, and both types of <code class="docutils literal notranslate"><span class="pre">struct</span></code>s interpret
|
||
these bytes the same way. The value stored here is <code class="docutils literal notranslate"><span class="pre">AF_INET</span></code> (the constant 2), which indicates an
|
||
IPv4 address. Code the checks this value as either type of struct would get the same answer for the
|
||
family. If the address is interpreted as <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code>, the three remaining fields
|
||
(<code class="docutils literal notranslate"><span class="pre">sin_port</span></code>, <code class="docutils literal notranslate"><span class="pre">sin_addr</span></code>, and <code class="docutils literal notranslate"><span class="pre">sin_zero</span></code>) occupy 14 bytes, the same amount of space as the
|
||
<code class="docutils literal notranslate"><span class="pre">sa_data</span></code> field in the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code> interpretation. In this particular example, the
|
||
<code class="docutils literal notranslate"><span class="pre">sin_port</span></code> field contains the value 80 (<code class="docutils literal notranslate"><span class="pre">0x50</span></code>), whereas the <code class="docutils literal notranslate"><span class="pre">sin_addr</span></code> field contains the
|
||
address 93.184.216.34 (<code class="docutils literal notranslate"><span class="pre">0x5db8d822</span></code>). Astute readers may notice there is a discrepancy in how the
|
||
<code class="docutils literal notranslate"><span class="pre">sin_family</span></code> and <code class="docutils literal notranslate"><span class="pre">sin_port</span></code> fields are interpreted. This discrepancy is caused by the concept
|
||
of <em>endianness</em>, which we will explain below.</p>
|
||
</div>
|
||
<p>IPv6 socket address <code class="docutils literal notranslate"><span class="pre">struct</span></code>s are similar in some respects. The <code class="docutils literal notranslate"><span class="pre">struct</span></code> is renamed
|
||
<code class="docutils literal notranslate"><span class="pre">sockaddr_in6</span></code> and the fields are renamed to <code class="docutils literal notranslate"><span class="pre">sin6_family</span></code>, <code class="docutils literal notranslate"><span class="pre">sin6_port</span></code>, and <code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code>.
|
||
Two additional fields (<code class="docutils literal notranslate"><span class="pre">sin6_flowinfo</span></code> and <code class="docutils literal notranslate"><span class="pre">sin6_scope_id</span></code>) are also defined for behavior that
|
||
exists in IPv6 but not in IPv4; these fields are used for specialized purposes that are beyond the
|
||
scope of this book.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* included by netinet/in.h */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr_in6</span> <span class="p">{</span>
|
||
<span class="n">sa_fmily_t</span> <span class="n">sin6_family</span><span class="p">;</span>
|
||
<span class="n">in_port_t</span> <span class="n">sin6_port</span><span class="p">;</span>
|
||
<span class="kt">uint32_t</span> <span class="n">sin6_flowinfo</span><span class="p">;</span>
|
||
<span class="k">struct</span> <span class="n">in6_addr</span> <span class="n">sin6_addr</span><span class="p">;</span> <span class="cm">/* IPv6 addresses are 128-bit */</span>
|
||
<span class="kt">uint32_t</span> <span class="n">sin6_scope_id</span><span class="p">;</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Despite their similar naming and ordering of fields, IPv6 socket address structs are considerably
|
||
larger in size. To be precise, consider the type of <code class="docutils literal notranslate"><span class="pre">sin_addr</span></code> compared with <code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code>. For
|
||
IPv4, the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">in_addr</span></code> type is an alias for <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code>—an unsigned 32-bit (4-byte) integer.
|
||
For IPv6, the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">in6_addr</span></code> contains a <code class="docutils literal notranslate"><span class="pre">union</span></code> of three different types. For readers
|
||
unfamiliar with C <code class="docutils literal notranslate"><span class="pre">union</span></code>s, the types are not distinct fields. Rather, the <code class="docutils literal notranslate"><span class="pre">__u6_addr</span></code> field of
|
||
the <code class="docutils literal notranslate"><span class="pre">struct</span></code> contains 16 bytes, but it can be interpreted in multiple ways. As such, the
|
||
<code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code> field alone is the size of the entire <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code> or <code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code> <code class="docutils literal notranslate"><span class="pre">struct</span></code>s.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* included by netinet/in.h */</span>
|
||
<span class="k">struct</span> <span class="n">in6_addr</span> <span class="p">{</span>
|
||
<span class="k">union</span> <span class="p">{</span>
|
||
<span class="kt">uint8_t</span> <span class="n">__u6_addr8</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span> <span class="cm">/* aliased as s6_addr */</span>
|
||
<span class="kt">uint16_t</span> <span class="n">__u6_addr16</span><span class="p">[</span><span class="mi">8</span><span class="p">];</span> <span class="cm">/* aliased as s6_addr16 */</span>
|
||
<span class="kt">uint32_t</span> <span class="n">__u6_addr32</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span> <span class="cm">/* aliased as s6_addr32 */</span>
|
||
<span class="p">}</span> <span class="n">__u6_addr</span><span class="p">;</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>The difference in the <code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code> field size is not a problem in practice. As the first field
|
||
(<code class="docutils literal notranslate"><span class="pre">sin6_family</span></code>) remains a constant size of 16 bits, this field can be used to determine which type
|
||
of <code class="docutils literal notranslate"><span class="pre">struct</span></code> is being used. The address field can then be accessed by explicitly casting to
|
||
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code>, <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code>, or <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in6</span></code> as needed. In the code, the
|
||
16 bytes of the <code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code> field can be viewed as an array of 16 <code class="docutils literal notranslate"><span class="pre">uint8_t</span></code> values, an array of
|
||
eight <code class="docutils literal notranslate"><span class="pre">uint16_t</span></code> values, or an array of four <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code> values; all three views refer to the
|
||
same sequence of bytes, and they all require the same size. Given that the syntax of unions can be
|
||
awkward, these fields are aliased as <code class="docutils literal notranslate"><span class="pre">s6_addr</span></code>, <code class="docutils literal notranslate"><span class="pre">s6_addr16</span></code>, and <code class="docutils literal notranslate"><span class="pre">s6_addr32</span></code>. <a class="reference external" href="Sockets.html#cl4-2">Code Listing 4.2</a>
|
||
shows how the alias makes the syntax cleaner to use.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-2"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.2:</span>
|
||
<span class="cm"> Accessing part of a union without and with an alias for the field</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="k">struct</span> <span class="n">in6_addr</span> <span class="n">addr</span><span class="p">;</span>
|
||
<span class="n">addr</span><span class="p">.</span><span class="n">__u6_addr</span><span class="p">.</span><span class="n">__u6_addr</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="cm">/* set first byte to 5 */</span>
|
||
<span class="n">addr</span><span class="p">.</span><span class="n">s6_addr</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="cm">/* same thing, but using the alias */</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3" id="sockstruct">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 4.4.2 </p><hr class="mt-1" />
|
||
<p>The following sequence of bytes illustrates an example of an IPv6 address <code class="docutils literal notranslate"><span class="pre">struct</span></code>. The first
|
||
observation to make is that this struct is 28 bytes in length, rather than the 16 bytes for IPv4 of
|
||
the generic <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code>. Due to this additional length, the bytes must be wrapped onto a
|
||
second line to make the table readable.</p>
|
||
<center>
|
||
<div class="col-12">
|
||
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center jmu-dark-purple-bg" colspan="16"><code class="text-light">struct sockaddr_in6</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="2"><code class="jmu-slate fs70 fs52">sin6_family</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="2"><code class="jmu-slate fs80 fs55">sin6_port</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">sin6_flowinfo</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="8"><code class="jmu-slate">sin6_addr</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="6.25%"><code>0a</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>50</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>26</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>06</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>28</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>02</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>20</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>01</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="8"><code class="jmu-slate">sin6_addr</code> <span class="jmu-slate">(continued)</span></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="4"><code class="jmu-slate">sin6_scope_id</code></td>
|
||
<td class="py-0" colspan="4" style="background: #dee2e6;"> </td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="6.25%"><code>02</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>48</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>18</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>93</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>25</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>c8</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>19</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>46</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0" colspan="4" style="background: #dee2e6;"> </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</center><p>As with <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code> and <code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code>, the first two bytes can be read independently of the rest
|
||
to determine the <code class="docutils literal notranslate"><span class="pre">sin6_family</span></code> field. The value 10 (<code class="docutils literal notranslate"><span class="pre">0x0a</span></code>) is the constant <code class="docutils literal notranslate"><span class="pre">AF_INET6</span></code>, which
|
||
indicates code working with a pointer to this <code class="docutils literal notranslate"><span class="pre">struct</span></code> should case it as an IPv6 address. This
|
||
example uses the same port (80) as <a href="Sockets.html#sockexampleipv4">Example 4.4.1</a>. The IP address shown in the
|
||
<code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code> field here would be <code class="docutils literal notranslate"><span class="pre">2606:2800:220:1:248:1893:25C8:1946</span></code>. Note that both of these
|
||
addresses correspond to the same (as of this writing) URL: <code class="docutils literal notranslate"><span class="pre">www.example.com</span></code>. This server can be
|
||
reached using either IPv4 or IPv6.</p>
|
||
<p>To illustrate the purpose of the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">in6_addr</span> <span class="pre">union</span></code>, consider the following version of the
|
||
IPv6 address from above. As before, we have written the address to wrap onto a second line for the
|
||
purposes of the table structure.</p>
|
||
<center>
|
||
<div class="col-12">
|
||
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="4"><code class="jmu-slate">s6_addr32[0]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="4"><code class="jmu-slate">s6_addr32[1]</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[0]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[1]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[2]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[3]</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="12.5%"><code>26</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>06</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>28</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>02</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>20</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>01</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="4"><code class="jmu-slate">s6_addr32[2]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="4"><code class="jmu-slate">s6_addr32[3]</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[4]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[5]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[6]</code></td>
|
||
<td class="py-0 center jmu-light-purple-bg" colspan="2"><code class="jmu-slate">s6_addr16[7]</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="12.5%"><code>02</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>48</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>18</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>93</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>25</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>c8</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>19</code></td>
|
||
<td class="py-0 center px-0" width="12.5%"><code>46</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</center><p>Each byte within the address can be accessed using the <code class="docutils literal notranslate"><span class="pre">s6_addr</span></code> array. If the address is stored
|
||
in the variable addr as declared in <a class="reference external" href="Sockets.html#cl4-2">Code Listing 4.2</a>, <code class="docutils literal notranslate"><span class="pre">addr.s6_addr[0]</span> <span class="pre">=</span> <span class="pre">0x26</span></code>, <code class="docutils literal notranslate"><span class="pre">addr.s6_addr[1]</span>
|
||
<span class="pre">=</span> <span class="pre">0x06</span></code>, and so on. However, the other types in this <code class="docutils literal notranslate"><span class="pre">union</span></code> allow the bytes to be grouped
|
||
together as needed by the code. The groupings are shown by the labels for the <code class="docutils literal notranslate"><span class="pre">s6_addr16</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">s6_addr32</span></code> arrays above. That is, using the same variable declaration from <a class="reference external" href="Sockets.html#cl4-2">Code Listing 4.2</a>,
|
||
<code class="docutils literal notranslate"><span class="pre">addr.s6_addr16[0]</span> <span class="pre">=</span> <span class="pre">0x2606</span></code> and <code class="docutils literal notranslate"><span class="pre">addr.s6_addr16[1]</span> <span class="pre">=</span> <span class="pre">0x2800</span></code>, whereas <code class="docutils literal notranslate"><span class="pre">addr.s6_addr32[0]</span> <span class="pre">=</span>
|
||
<span class="pre">0x26062800</span></code>. The <code class="docutils literal notranslate"><span class="pre">union</span></code> type allows the programmer to use whichever interpretation is convenient.</p>
|
||
</div>
|
||
<p>The internal representations of <code class="docutils literal notranslate"><span class="pre">in_addr</span></code> and <code class="docutils literal notranslate"><span class="pre">in6_addr</span></code> are different from the standard
|
||
notation used for IP addresses. For instance, readers may be familiar with the <em>dotted
|
||
decimal</em> notation of IPv4 addresses, as illustrated by the <a class="reference internal" href="Glossary.html#term-loopback-address"><span class="xref std std-term">loopback address</span></a> 127.0.0.1 that
|
||
refers to the local host machine. This format is used for human readability, but the actual IP
|
||
address is stored as a 32-bit value, with each byte corresponding to one of the dotted fields. In
|
||
the case of the loopback, the IP address is <code class="docutils literal notranslate"><span class="pre">0x7f000001</span></code> (recall that <code class="docutils literal notranslate"><span class="pre">0x7f</span></code> is the same as the
|
||
decimal number 127). Similarly, IPv6 addresses are typically formatted as a colon-delimited list of
|
||
groups of four hexadecimal digits, such as <code class="docutils literal notranslate"><span class="pre">1122:3344:5566:7788:99aa:bbcc:ddee:ff00</span></code>. Leading
|
||
zeros can be compressed, and consecutive sections of zeros can be replaced with a double colon. As
|
||
such, the IPv6 loopback address can be written as <code class="docutils literal notranslate"><span class="pre">0:0:0:0:0:0:0:1</span></code>, or simply <code class="docutils literal notranslate"><span class="pre">::1</span></code>. However,
|
||
the internal representation is the full 16-byte sequence of values.</p>
|
||
<p>In both IPv4 and IPv6 the sin_port and sin6_port fields require special handling, due to the issue
|
||
of <em>endianness</em>. Recall that multi-byte numbers, such as a 16-bit unsigned integer, can be
|
||
stored according to either <em>big endian</em> or <em>little endian</em> format depending on the CPU architecture.
|
||
In a big endian architecture, the <cite>most significant</cite> byte (i.e., the <em>big end</em> of the number) is
|
||
placed at the lowest memory address; this relationship can be captured with the mnemonic, “big end
|
||
at the bottom.” In contrast, a little endian architecture would place the <cite>least significant</cite> byte
|
||
at the lowest address; here, the mnemonic is “little end at the lowest.” As an illustration,
|
||
consider <a class="reference external" href="Sockets.html#cl4-3">Code Listing 4.3</a>. By casting the address of the <code class="docutils literal notranslate"><span class="pre">uint16_t</span></code> variable—which would actually
|
||
be the address of its byte at the lowest numerical address—as a <code class="docutils literal notranslate"><span class="pre">uint8_t</span></code> pointer, the two bytes
|
||
can be accessed individually.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-3"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.3:</span>
|
||
<span class="cm"> Casting and pointer arithmetic can illustrate endianness</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">address</span><span class="p">;</span>
|
||
<span class="n">address</span><span class="p">.</span><span class="n">sin_port</span> <span class="o">=</span> <span class="n">htons</span> <span class="p">(</span><span class="mi">4096</span><span class="p">);</span> <span class="cm">/* see below */</span>
|
||
<span class="cm">/* Cast the address to access each byte individually */</span>
|
||
<span class="kt">uint8_t</span> <span class="o">*</span><span class="n">as_array</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span> <span class="o">&</span><span class="n">address</span><span class="p">.</span><span class="n">sin_port</span><span class="p">;</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"%p stores %"</span> <span class="n">PRI8x</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="o">&</span><span class="n">as_array</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">as_array</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"%p stores %"</span> <span class="n">PRI8x</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="o">&</span><span class="n">as_array</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">as_array</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>If we assume the <code class="docutils literal notranslate"><span class="pre">address.sin_port</span></code> field resides at address <code class="docutils literal notranslate"><span class="pre">0xbfff1234</span></code> (thus also occupying
|
||
<code class="docutils literal notranslate"><span class="pre">0xbfff1235</span></code>), the variable layout in memory would vary based on the CPU architecture:</p>
|
||
<div class="row">
|
||
<div class="col-md-2"> </div>
|
||
<div class="col-md-4">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th colspan="2" class="py-0 center">Big Endian</th>
|
||
</tr>
|
||
<tr>
|
||
<th class="py-0 center">Address</th>
|
||
<th class="py-0 center">Value</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center"><code>bfff1235</code></td>
|
||
<td class="py-0 center"><code>00</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center"><code>bfff1234</code></td>
|
||
<td class="py-0 center"><code>10</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th colspan="2" class="py-0 center">Little Endian</th>
|
||
</tr>
|
||
<tr>
|
||
<th class="py-0 center">Address</th>
|
||
<th class="py-0 center">Value</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center"><code>bfff1235</code></td>
|
||
<td class="py-0 center"><code>10</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center"><code>bfff1234</code></td>
|
||
<td class="py-0 center"><code>00</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-2"> </div>
|
||
<div class="col-md-8 center">
|
||
Table 4.3: Placement of bytes in memory depends on CPU endianness
|
||
</div>
|
||
</div>
|
||
<br /><p>While most modern CPU architectures use a little endian format, network protocols use big endian.
|
||
Furthermore, since the sender and receiver hosts may have different CPU architectures, they may also
|
||
differ in their endianness. To overcome this problem, multi-byte socket address fields that will be
|
||
sent across the network require attention to endianness. The simplest way to achieve this is to use
|
||
the C functions <code class="docutils literal notranslate"><span class="pre">htons()</span></code>, <code class="docutils literal notranslate"><span class="pre">htonl()</span></code>, <code class="docutils literal notranslate"><span class="pre">ntohs()</span></code>, and <code class="docutils literal notranslate"><span class="pre">ntohl()</span></code>. When the process is setting
|
||
up the socket or sending data, use the <code class="docutils literal notranslate"><span class="pre">hton</span></code> (<em>host to network</em>) versions; as an example, refer
|
||
back to the last line of <a class="reference external" href="Sockets.html#cl4-1">Code Listing 4.1</a>. At the other end, when a process reads data
|
||
from the network, it will use the <code class="docutils literal notranslate"><span class="pre">ntoh</span></code> (<em>network to host</em>) version. Assuming both hosts follow
|
||
this convention, neither host will require any advance knowledge of the other host’s CPU
|
||
architecture endianness.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <arpa/inet.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">uint32_t</span> <span class="pre">htonl</span> <span class="pre">(uint32_t</span> <span class="pre">hostlong);</span></code></dt>
|
||
<dd>Convert a 32-bit unsigned integer from host endian format to network endian format.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">uint16_t</span> <span class="pre">htons</span> <span class="pre">(uint16_t</span> <span class="pre">hostshort);</span></code></dt>
|
||
<dd>Convert a 16-bit unsigned integer from host endian format to network endian format.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">uint32_t</span> <span class="pre">ntohl</span> <span class="pre">(uint32_t</span> <span class="pre">netlong);</span></code></dt>
|
||
<dd>Convert a 32-bit unsigned integer from network endian format to host endian format.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">uint16_t</span> <span class="pre">ntohs</span> <span class="pre">(uint16_t</span> <span class="pre">netshort);</span></code></dt>
|
||
<dd>Convert a 16-bit unsigned integer from network endian format to host endian format.</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="topic border border-dark rounded-lg alert-danger px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-BugWarning.png"><img alt="Decorative bug warning" src="_images/CSF-Images-BugWarning.png" style="width: 90%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Bug Warning</p><hr class="mt-1" />
|
||
<p>Within the <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code> and <code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code> structures, only fields that are intended to be sent
|
||
across the network need to be formatted with the <em>host to network</em> functions. Other fields must not
|
||
be formatted in this way, as they are only used by the local host machine; flipping the byte order
|
||
of these values would produce incorrect results. In practice, only the port field needs to be
|
||
formatted with <code class="docutils literal notranslate"><span class="pre">htons()</span></code>; IP addresses are generally not hard-coded and helper functions format
|
||
these values transparently.</p>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="client-socket-interface">
|
||
<h2>4.4.2. Client Socket Interface<a class="headerlink" href="Sockets.html#client-socket-interface" title="Permalink to this headline">¶</a></h2>
|
||
<p>Once a client process has created a socket, the next step is to build the socket address structure
|
||
and to establish a connection with the socket at the server host. The client is primarily concerned
|
||
with specifying the IP address of the server and the associated port number. In the case of a
|
||
connection-less protocol like UDP, this step does not actually involve contacting the server;
|
||
rather, this step just involves configuring the socket’s peer IP address.</p>
|
||
<p>While there are standard port numbers for many applications, IP addresses should not be hard-coded,
|
||
as they can change. Instead, <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> provides an interface to look up an IP address by the
|
||
standard text format used in URIs. This string is passed as the first argument, <code class="docutils literal notranslate"><span class="pre">nodename</span></code>. The
|
||
<code class="docutils literal notranslate"><span class="pre">servname</span></code> parameter indicates a desired service, such as <code class="docutils literal notranslate"><span class="pre">"http"</span></code>. The <code class="docutils literal notranslate"><span class="pre">hints</span></code> parameter can
|
||
be used to limit the list of results, such as restricting the domain to <code class="docutils literal notranslate"><span class="pre">AF_INET</span></code> (IPv4) or
|
||
<code class="docutils literal notranslate"><span class="pre">AF_INET6</span></code> (IPv6), or limiting the type to <code class="docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code> or <code class="docutils literal notranslate"><span class="pre">SOCK_DGRAM</span></code>. The final parameter,
|
||
<code class="docutils literal notranslate"><span class="pre">res</span></code>, is a call-by-reference parameter that will be set to point to a linked list of address structures.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <netdb.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">getaddrinfo</span> <span class="pre">(const</span> <span class="pre">char</span> <span class="pre">*nodename,</span> <span class="pre">const</span> <span class="pre">char</span> <span class="pre">*servname,</span> <span class="pre">const</span> <span class="pre">struct</span> <span class="pre">addrinfo</span> <span class="pre">*hints,</span> <span class="pre">struct</span> <span class="pre">addrinfo</span> <span class="pre">**res);</span></code></dt>
|
||
<dd>Translate a human-readable hostname into an IP address, typically with the help of DNS.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">freeaddrinfo</span> <span class="pre">(struct</span> <span class="pre">addrinfo</span> <span class="pre">*ai);</span></code></dt>
|
||
<dd>Free all address information structures in the linked list beginning at ai.</dd>
|
||
</dl>
|
||
</div>
|
||
<p>Both the <code class="docutils literal notranslate"><span class="pre">hints</span></code> and <code class="docutils literal notranslate"><span class="pre">res</span></code> parameters use the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code> structure, defined in
|
||
<code class="docutils literal notranslate"><span class="pre">netdb.h</span></code>. The <code class="docutils literal notranslate"><span class="pre">hints</span></code> argument initializes all fields to zero, setting the int fields as
|
||
desired. For example, setting <code class="docutils literal notranslate"><span class="pre">hints.ai_family</span></code> to <code class="docutils literal notranslate"><span class="pre">AF_INET</span></code> would get results only for IPv4; to
|
||
get all families, the value can be left as zero or explicitly set as <code class="docutils literal notranslate"><span class="pre">AF_UNSPEC</span></code>. Similarly,
|
||
setting hints.ai_socktype to <code class="docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code> would yield only byte stream sockets (e.g., those used
|
||
in TCP). In the results list, the <code class="docutils literal notranslate"><span class="pre">ai_addr</span></code> field would point to a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code> as defined
|
||
previously. Note that <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> puts all values into the struct in the correct endianness
|
||
needed for later functions, so no additional conversion is needed. Since <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>
|
||
dynamically allocates the results list, the <code class="docutils literal notranslate"><span class="pre">res</span></code> field should be passed to <code class="docutils literal notranslate"><span class="pre">freeaddrinfo()</span></code> to free the memory.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* defined in netdb.h */</span>
|
||
<span class="k">struct</span> <span class="n">addrinfo</span> <span class="p">{</span>
|
||
<span class="kt">int</span> <span class="n">ai_flags</span><span class="p">;</span>
|
||
<span class="kt">int</span> <span class="n">ai_family</span><span class="p">;</span>
|
||
<span class="kt">int</span> <span class="n">ai_socktype</span><span class="p">;</span>
|
||
<span class="kt">int</span> <span class="n">ai_protocol</span><span class="p">;</span>
|
||
<span class="kt">socklen_t</span> <span class="n">ai_addrlen</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">ai_canonname</span><span class="p">;</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr</span> <span class="o">*</span><span class="n">ai_addr</span><span class="p">;</span>
|
||
<span class="k">struct</span> <span class="n">addrinfo</span> <span class="o">*</span><span class="n">ai_next</span><span class="p">;</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>When building applications to connect to a server, the <code class="docutils literal notranslate"><span class="pre">ai_addr</span></code> field can be passed without
|
||
casting. However, it is often beneficial to print the address in a readable format, such as when
|
||
writing to a log file. The <code class="docutils literal notranslate"><span class="pre">inet_ntoa()</span></code> and <code class="docutils literal notranslate"><span class="pre">inet_ntop()</span></code> functions perform this formatting. Of
|
||
these two, the <code class="docutils literal notranslate"><span class="pre">inet_ntoa()</span></code> function is older and only supports IPv4. This function takes a
|
||
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">in_addr</span></code> parameter, which would be the <code class="docutils literal notranslate"><span class="pre">sin_addr</span></code> field of a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code>. The
|
||
return value is a pointer to a statically allocated location containing the string. As such, the
|
||
pointer does not (and cannot) need to be freed later. On the other hand, <code class="docutils literal notranslate"><span class="pre">inet_ntop()</span></code> works with
|
||
both IPv4 and IPv6, relying on the <code class="docutils literal notranslate"><span class="pre">af</span></code> parameter to distinguish between the two. The <code class="docutils literal notranslate"><span class="pre">src</span></code>
|
||
argument points to the <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code> to translate; note that this parameter uses a <code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*</span></code> type,
|
||
and the function will cast it based on the <code class="docutils literal notranslate"><span class="pre">af</span></code> argument. The <code class="docutils literal notranslate"><span class="pre">dst</span></code> argument is a pointer to a
|
||
buffer to write the string into, with size indicating the length of the buffer. If the address can
|
||
be translated properly, the function returns a pointer to the string, which should match the address
|
||
of the buffer.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <arpa/inet.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">*inet_ntoa</span> <span class="pre">(struct</span> <span class="pre">in_addr</span> <span class="pre">in);</span></code></dt>
|
||
<dd>Convert an IPv4 address into a string using dotted decimal notation.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*inet_ntop</span> <span class="pre">(int</span> <span class="pre">af,</span> <span class="pre">const</span> <span class="pre">void</span> <span class="pre">*src,</span> <span class="pre">char</span> <span class="pre">*dst,</span> <span class="pre">socklen_t</span> <span class="pre">size);</span></code></dt>
|
||
<dd>Convert an IP address (either IPv4 or IPv6) into a string format.</dd>
|
||
</dl>
|
||
</div>
|
||
<p><a class="reference external" href="Sockets.html#cl4-4">Code Listing 4.4</a> illustrates how these functions can be used along with <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>
|
||
to translate a hostname (assumed to be declared with a value such as <code class="docutils literal notranslate"><span class="pre">"www.example.com"</span></code>) into an
|
||
IPv6 readable address format. The <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> internal implementation typically relies on the
|
||
<a class="reference internal" href="Glossary.html#term-domain-name-system"><span class="xref std std-term">Domain Name System</span></a> (DNS) protocol to look up the IP address. In this initial version, each
|
||
of the results in the server list are confirmed to be an IPv6 address. The <code class="docutils literal notranslate"><span class="pre">ai_addr</span></code> field is then
|
||
cast to the appropriate socket address <code class="docutils literal notranslate"><span class="pre">struct</span></code> and its <code class="docutils literal notranslate"><span class="pre">sin6_addr</span></code> field is passed to the
|
||
<code class="docutils literal notranslate"><span class="pre">inet_ntop()</span></code> function for formatting. This implementation could be modified to print IPv4
|
||
addresses correctly by changing only the constants and field names as described previously; the
|
||
buffer size would need to use the constant <code class="docutils literal notranslate"><span class="pre">INET_ADDRSTRLEN</span></code>, as well.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-4"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.4:</span>
|
||
<span class="cm"> Utility program that prints IPv6 addresses as a readable string</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="k">struct</span> <span class="n">addrinfo</span> <span class="n">hints</span><span class="p">,</span> <span class="o">*</span><span class="n">server_list</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">*</span><span class="n">server</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="n">memset</span> <span class="p">(</span><span class="o">&</span><span class="n">hints</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">hints</span><span class="p">));</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_family</span> <span class="o">=</span> <span class="n">AF_INET6</span><span class="p">;</span> <span class="cm">/* change to AF_INET for IPv4 */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_socktype</span> <span class="o">=</span> <span class="n">SOCK_STREAM</span><span class="p">;</span> <span class="cm">/* limit to byte-streams */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_protocol</span> <span class="o">=</span> <span class="n">IPPROTO_TCP</span><span class="p">;</span> <span class="cm">/* create as a TCP socket */</span>
|
||
|
||
<span class="cm">/* Get a list of addresses at hostname that serve HTTP */</span>
|
||
<span class="n">getaddrinfo</span> <span class="p">(</span><span class="n">hostname</span><span class="p">,</span> <span class="s">"http"</span><span class="p">,</span> <span class="o">&</span><span class="n">hints</span><span class="p">,</span> <span class="o">&</span><span class="n">server_list</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Traverse through the linked list of results */</span>
|
||
<span class="k">for</span> <span class="p">(</span><span class="n">server</span> <span class="o">=</span> <span class="n">server_list</span><span class="p">;</span> <span class="n">server</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="n">server</span> <span class="o">=</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_next</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">server</span><span class="o">-></span><span class="n">ai_family</span> <span class="o">==</span> <span class="n">AF_INET6</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* Cast ai_addr to an IPv6 socket address */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr_in6</span> <span class="o">*</span><span class="n">addr</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr_in6</span> <span class="o">*</span><span class="p">)</span><span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Allocate a buffer to store the IPv6 string */</span>
|
||
<span class="kt">char</span> <span class="n">in6addr</span><span class="p">[</span><span class="n">INET6_ADDRSTRLEN</span><span class="p">];</span>
|
||
<span class="n">assert</span> <span class="p">(</span><span class="n">inet_ntop</span> <span class="p">(</span><span class="n">AF_INET6</span><span class="p">,</span> <span class="o">&</span><span class="n">addr</span><span class="o">-></span><span class="n">sin6_addr</span><span class="p">,</span> <span class="n">in6addr</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">in6addr</span><span class="p">))</span>
|
||
<span class="o">!=</span> <span class="nb">NULL</span><span class="p">);</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"IPv6 address: %s</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span> <span class="n">in6addr</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
<span class="n">freeaddrinfo</span> <span class="p">(</span><span class="n">server_list</span><span class="p">);</span> <span class="cm">/* Free allocated linked list data */</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p><a class="reference external" href="Sockets.html#cl4-5">Code Listing 4.5</a> shows how the if-block from <a class="reference external" href="Sockets.html#cl4-4">Code Listing 4.4</a> could use <code class="docutils literal notranslate"><span class="pre">inet_ntoa()</span></code>
|
||
instead of <code class="docutils literal notranslate"><span class="pre">inet_ntop()</span></code>. For IPv4, the two functions produce identical output, so either one can be used.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-5"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.5:</span>
|
||
<span class="cm"> Additional code for printing out an IPv4 in dotted decimal format</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">server</span><span class="o">-></span><span class="n">ai_family</span> <span class="o">==</span> <span class="n">AF_INET</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* Cast ai_addr to an IPv4 socket address */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="o">*</span><span class="n">addr</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="o">*</span><span class="p">)</span><span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">;</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"IPv4 address: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">inet_ntoa</span> <span class="p">(</span><span class="n">addr</span><span class="o">-></span><span class="n">sin_addr</span><span class="p">));</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p><a class="reference external" href="Sockets.html#cl4-3">Code Listing 4.3</a> showed how the port field could be explicitly set with a variable
|
||
assignment. While it may not be apparent, <a class="reference external" href="Sockets.html#cl4-4">Code Listing 4.4</a> illustrates a second,
|
||
preferred way to handle this assignment. Specifically, <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> puts the port number in
|
||
socket address based on standard, <a class="reference internal" href="Glossary.html#term-well-known-port"><span class="xref std std-term">well-known ports</span></a>. In this case, the
|
||
parameter <code class="docutils literal notranslate"><span class="pre">"http"</span></code> maps to port number 80. <a class="reference external" href="Sockets.html#tbl4-4">Table 4.4</a> lists the port numbers for some
|
||
common applications. Note that some services, such as FTP and Telnet, are discouraged because they
|
||
offer no security guarantees; Telnet, for instance, allows anyone with a packet sniffer to discover
|
||
a user’s password when logging in to a remote server. Instead, the secure approach is to run these
|
||
protocols on top of SSH.</p>
|
||
<div class="row center">
|
||
<div class="col-md-6">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="py-0 center">Port</th>
|
||
<th class="py-0 center">Name</th>
|
||
<th class="py-0 center">Service</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center">21</td>
|
||
<td class="py-0 center">FTP</td>
|
||
<td class="py-0">Insecure file transfer</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">22</td>
|
||
<td class="py-0 center">SSH</td>
|
||
<td class="py-0">Secure shell</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">23</td>
|
||
<td class="py-0 center">Telnet</td>
|
||
<td class="py-0">Insecure remote access</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">25</td>
|
||
<td class="py-0 center">SMTP</td>
|
||
<td class="py-0">Email delivery</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">53</td>
|
||
<td class="py-0 center">DNS</td>
|
||
<td class="py-0">IP address lookup</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">67</td>
|
||
<td class="py-0 center">DHCP</td>
|
||
<td class="py-0">IP address assignment</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">68</td>
|
||
<td class="py-0 center">DHCP</td>
|
||
<td class="py-0">IP address assignment</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">80</td>
|
||
<td class="py-0 center">HTTP</td>
|
||
<td class="py-0">Web page</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">88</td>
|
||
<td class="py-0 center">Kerberos</td>
|
||
<td class="py-0">Authentication</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="py-0 center">Port</th>
|
||
<th class="py-0 center">Name</th>
|
||
<th class="py-0 center">Service</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center">110</td>
|
||
<td class="py-0 center">POP3</td>
|
||
<td class="py-0">POP email access</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">123</td>
|
||
<td class="py-0 center">NTP</td>
|
||
<td class="py-0">Time synchronization</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">143</td>
|
||
<td class="py-0 center">IMAP</td>
|
||
<td class="py-0">IMAP email access</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">194</td>
|
||
<td class="py-0 center">IRC</td>
|
||
<td class="py-0">Internet chat service</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">389</td>
|
||
<td class="py-0 center">LDAP</td>
|
||
<td class="py-0">Authentication</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">443</td>
|
||
<td class="py-0 center">HTTPS</td>
|
||
<td class="py-0">Secure web page</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">530</td>
|
||
<td class="py-0 center">RPC</td>
|
||
<td class="py-0">Remote procedure call</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">631</td>
|
||
<td class="py-0 center">IPP</td>
|
||
<td class="py-0">Internet printing</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">993</td>
|
||
<td class="py-0 center">IMAPS</td>
|
||
<td class="py-0">Secure IMAP access</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-10 center">
|
||
Table 4.4: List of common well-known ports
|
||
</div>
|
||
<br /><div class="topic border border-dark rounded-lg bg-light px-2 mb-3" id="sockexampleipv6">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 4.4.3 </p><hr class="mt-1" />
|
||
<p>The relationship between the <code class="docutils literal notranslate"><span class="pre">struct</span></code>s can get confusing in code, due to the casting and pointer
|
||
dereferences involved. To illustrate their connections, assume that <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> returns a list
|
||
with two nodes containing the addresses in <a href="Sockets.html#sockexampleipv4">Example 4.4.1</a> and <a href="Sockets.html#sockstruct">Example 4.4.2</a>.
|
||
This list could be visualized as follows:</p>
|
||
<div class="figure mb-2 align-center">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images.4.EX.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Visualization of a linked list of two struct addrinfo nodes" src="_images/CSF-Images.4.EX.png" style="width: 80%;" /></a>
|
||
</div>
|
||
<p>The key observertion is that the IP addresses (in the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code> and <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in6</span></code>)
|
||
are stored separately from the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code> nodes. Both nodes indicate the address is for a TCP
|
||
server (indicated by <code class="docutils literal notranslate"><span class="pre">ai_socktype</span> <span class="pre">=</span> <span class="pre">SOCK_STREAM</span></code> and <code class="docutils literal notranslate"><span class="pre">ai_protocol</span> <span class="pre">=</span> <span class="pre">IPPROTO_TCP</span></code>). We can determine
|
||
the type of address by checking <code class="docutils literal notranslate"><span class="pre">ai_family</span></code>, which is set to 2 (<code class="docutils literal notranslate"><span class="pre">AF_INET</span></code>) for IPv4 or 10
|
||
(<code class="docutils literal notranslate"><span class="pre">AF_INET6</span></code>) for IPv6. We could also determine this information indirectly by noting the <code class="docutils literal notranslate"><span class="pre">ai_addrlen</span></code>
|
||
field that indicates the address length (4 for IPv4, 16 for IPv6).</p>
|
||
<p>In <a class="reference external" href="Sockets.html#cl4-5">Code Listing 4.5</a>, the <code class="docutils literal notranslate"><span class="pre">server</span></code> variable would point to the first <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code>.
|
||
Then the <code class="docutils literal notranslate"><span class="pre">addr</span></code> variable would point to the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code> shown just below it, allowing
|
||
the call to <code class="docutils literal notranslate"><span class="pre">inet_ntoa</span> <span class="pre">(addr->sin_addr)</span></code> on the address. <a class="reference external" href="Sockets.html#cl4-6">Code Listing 4.6</a> uses the
|
||
next <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code> containing the pointer to the IPv6 address. This pointer can then be passed
|
||
to <code class="docutils literal notranslate"><span class="pre">inet_ntop()</span></code> to print the address.</p>
|
||
<p><a href="Sockets.html#sockexampleipv4">Example 4.4.1</a> and <a href="Sockets.html#sockstruct">Example 4.4.2</a> detailed the byte contents of the
|
||
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code> and <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in6</span></code>, respectively. We can examime the first <code class="docutils literal notranslate"><span class="pre">struct</span>
|
||
<span class="pre">addrinfo</span></code> as shown in the following table. In this case, we assume that the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr_in</span></code>
|
||
instance is at memory location <code class="docutils literal notranslate"><span class="pre">0x5581f7459560</span></code> (as indicated by the <code class="docutils literal notranslate"><span class="pre">ai_addr</span></code> pointer), while
|
||
the other <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code> is stored at <code class="docutils literal notranslate"><span class="pre">0x5581f7453040</span></code> (as indicated by the <code class="docutils literal notranslate"><span class="pre">ai_next</span></code>
|
||
pointer).</p>
|
||
<center>
|
||
<div class="col-12">
|
||
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center jmu-dark-purple-bg" colspan="16"><code class="text-light">struct addrinfo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">ai_flags</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">ai_family</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">ai_socktype</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">ai_protocol</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>02</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>01</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>06</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
</tr>
|
||
</table>
|
||
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">ai_flags</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="4"><code class="jmu-slate">[PADDING]</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="8"><code class="jmu-slate">ai_addr</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="6.25%"><code>10</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>76</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>65</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>72</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>0a</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>60</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>95</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>45</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>f7</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>81</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>55</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
</tr>
|
||
</table>
|
||
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="8"><code class="jmu-slate">ai_canonname</code></td>
|
||
<td class="py-0 center px-0 jmu-light-purple-bg" colspan="8"><code class="jmu-slate">ai_next</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>40</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>30</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>45</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>f7</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>81</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>55</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
<td class="py-0 center px-0" width="6.25%"><code>00</code></td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</center><p>Note that these <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code> instances form a linked list of possible address responses (each
|
||
of which point to external <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code> instances). In this example, since <code class="docutils literal notranslate"><span class="pre">ai_next</span></code> is
|
||
<code class="docutils literal notranslate"><span class="pre">NULL</span></code>, there are no more <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">addrinfo</span></code> entries in the list.</p>
|
||
</div>
|
||
<p>Once the address information is established, it can be passed to the <code class="docutils literal notranslate"><span class="pre">connect()</span></code> function to
|
||
establish the initial connection to the socket at a server address, so long as it is accepting
|
||
requests. If TCP is the transport layer protocol used, <code class="docutils literal notranslate"><span class="pre">connect()</span></code> will send an initial message to
|
||
the server host process to initiate the TCP <a class="reference internal" href="Glossary.html#term-tcp-handshake"><span class="xref std std-term">3-way handshake</span></a>, making the server aware of the
|
||
connection. If UDP or another connectionless protocol is used, <code class="docutils literal notranslate"><span class="pre">connect()</span></code> simply sets the IP
|
||
address of the peer (i.e., the server) in the client host’s socket.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <sys/socket.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">connect</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">const</span> <span class="pre">struct</span> <span class="pre">sockaddr</span> <span class="pre">*address,</span> <span class="pre">socklen_t</span> <span class="pre">address_len);</span></code></dt>
|
||
<dd>Connect to a server or set the peer address of a connectionless server socket.</dd>
|
||
</dl>
|
||
</div>
|
||
<p>Building on the previous examples, <a class="reference external" href="Sockets.html#cl4-6">Code Listing 4.6</a> shows how the results from
|
||
<code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> can be used to connect to the server. In this example, we are creating a TCP
|
||
connection over IPv4 to the designated <code class="docutils literal notranslate"><span class="pre">hostname</span></code>. Based on the hints fields and the second
|
||
parameter to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>, every address returned in the <code class="docutils literal notranslate"><span class="pre">server_list</span></code> will be configured to
|
||
connect to a web server running HTTP. When the for-loop ends, the process is either connected to the
|
||
server to start an HTTP session or there is no socket connection available. In the latter case, the
|
||
<code class="docutils literal notranslate"><span class="pre">socketfd</span></code> would be -1, and the client should recognize the failed connection.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-6"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.6:</span>
|
||
<span class="cm"> Client code that will connect to a web server for an HTTP session</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Declare an IPv4 socket for TCP */</span>
|
||
<span class="kt">int</span> <span class="n">socketfd</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
|
||
<span class="k">struct</span> <span class="n">addrinfo</span> <span class="n">hints</span><span class="p">,</span> <span class="o">*</span><span class="n">server_list</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">*</span><span class="n">server</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="n">memset</span> <span class="p">(</span><span class="o">&</span><span class="n">hints</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">hints</span><span class="p">));</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_family</span> <span class="o">=</span> <span class="n">AF_INET</span><span class="p">;</span> <span class="cm">/* grab IPv4 only */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_socktype</span> <span class="o">=</span> <span class="n">SOCK_STREAM</span><span class="p">;</span> <span class="cm">/* limit to byte streams */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_protocol</span> <span class="o">=</span> <span class="n">IPPROTO_TCP</span><span class="p">;</span> <span class="cm">/* create as a TCP socket */</span>
|
||
|
||
<span class="cm">/* Get a list of addresses at hostname that serve HTTP */</span>
|
||
<span class="n">getaddrinfo</span> <span class="p">(</span><span class="n">hostname</span><span class="p">,</span> <span class="s">"http"</span><span class="p">,</span> <span class="o">&</span><span class="n">hints</span><span class="p">,</span> <span class="o">&</span><span class="n">server_list</span><span class="p">);</span>
|
||
|
||
<span class="k">for</span> <span class="p">(</span><span class="n">server</span> <span class="o">=</span> <span class="n">server_list</span><span class="p">;</span> <span class="n">server</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="n">server</span> <span class="o">=</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_next</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* Attempt to create a TCP IPv4 socket */</span>
|
||
<span class="k">if</span> <span class="p">((</span><span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">server</span><span class="o">-></span><span class="n">ai_family</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_socktype</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">continue</span><span class="p">;</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">connect</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addrlen</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">break</span><span class="p">;</span>
|
||
<span class="n">close</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">);</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
<span class="n">freeaddrinfo</span> <span class="p">(</span><span class="n">server_list</span><span class="p">);</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">socketfd</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* ... begin HTTP session here ... */</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="server-socket-interface">
|
||
<h2>4.4.3. Server Socket Interface<a class="headerlink" href="Sockets.html#server-socket-interface" title="Permalink to this headline">¶</a></h2>
|
||
<p>Setting up the server socket involves a different sequence of steps from the client process. As
|
||
before, <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> provides an interface for configuring the socket address information, but
|
||
the arguments will be structured differently. For starters, we are not using <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> to
|
||
perform a DNS query on a remote host; instead, we are setting up the socket based on the current
|
||
host’s existing IP address. In addition, if the server is part of a custom application, rather than
|
||
a standard utility like a web server, the port number will not be identified as one of the well-known ports.</p>
|
||
<p>Code Listing 4.7 shows the differences in the parameters passed to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> for a server.
|
||
First, the <code class="docutils literal notranslate"><span class="pre">hints.ai_flags</span></code> field is set to <code class="docutils literal notranslate"><span class="pre">AI_PASSIVE</span></code> and the <code class="docutils literal notranslate"><span class="pre">nodename</span></code> argument is set to
|
||
<code class="docutils literal notranslate"><span class="pre">NULL</span></code>. This combination specifies that the socket will use the local host’s IP address and will
|
||
be listening for incoming requests. Next, the <code class="docutils literal notranslate"><span class="pre">servname</span></code> parameter has been changed to <code class="docutils literal notranslate"><span class="pre">"8000"</span></code>
|
||
to demonstrate how a custom port number can be used. Systems have existing processes set up for
|
||
well-known ports, and each port number can only be assigned to a single process. Consequently, if we
|
||
want to build our own web server, we would need to pick a random port number to use, 8000 in this
|
||
case. To connect to this server once it is running, the client from Code Listing 4.6 would also need
|
||
to be modified to pass <code class="docutils literal notranslate"><span class="pre">"8000"</span></code> to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> instead of <code class="docutils literal notranslate"><span class="pre">"http"</span></code> as the <code class="docutils literal notranslate"><span class="pre">servname</span></code> argument.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-7"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.7:</span>
|
||
<span class="cm"> Getting socket address information for a server</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="k">struct</span> <span class="n">addrinfo</span> <span class="n">hints</span><span class="p">,</span> <span class="o">*</span><span class="n">server_info</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="n">memset</span> <span class="p">(</span><span class="o">&</span><span class="n">hints</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">hints</span><span class="p">));</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_family</span> <span class="o">=</span> <span class="n">AF_INET</span><span class="p">;</span> <span class="cm">/* grab IPv4 only */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_socktype</span> <span class="o">=</span> <span class="n">SOCK_STREAM</span><span class="p">;</span> <span class="cm">/* specify byte-streaming */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_flags</span> <span class="o">=</span> <span class="n">AI_PASSIVE</span><span class="p">;</span> <span class="cm">/* use default IP address */</span>
|
||
<span class="n">hints</span><span class="p">.</span><span class="n">ai_protocol</span> <span class="o">=</span> <span class="n">IPPROTO_TCP</span><span class="p">;</span> <span class="cm">/* create as a TCP socket */</span>
|
||
|
||
<span class="cm">/* Get a list of addresses at hostname that serve HTTP */</span>
|
||
<span class="n">getaddrinfo</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="s">"8000"</span><span class="p">,</span> <span class="o">&</span><span class="n">hints</span><span class="p">,</span> <span class="o">&</span><span class="n">server_info</span><span class="p">);</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Once the socket address information has been configured, the process can then make a sequence of
|
||
function calls to become a server. Typically (though not required), the first call is to
|
||
<code class="docutils literal notranslate"><span class="pre">setsockopt()</span></code> to configure the socket with the <code class="docutils literal notranslate"><span class="pre">SO_REUSEADDR</span></code> option. This option avoids a
|
||
common error during the next step, <code class="docutils literal notranslate"><span class="pre">bind()</span></code>. The <code class="docutils literal notranslate"><span class="pre">bind()</span></code> call links the port number with the
|
||
current process. Sometimes when a port number is reused, a timing problem can cause the previous
|
||
process (which is no longer running) to fail to release the port fully. Setting the <code class="docutils literal notranslate"><span class="pre">SO_REUSEADDR</span></code>
|
||
option tells <code class="docutils literal notranslate"><span class="pre">bind()</span></code> to ignore this and forcefully replace the port association.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <sys/socket.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">setsockopt</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">int</span> <span class="pre">level,</span> <span class="pre">int</span> <span class="pre">option_name,</span> <span class="pre">const</span> <span class="pre">void</span> <span class="pre">*option_value,</span> <span class="pre">socklen_t</span> <span class="pre">option_len);</span></code></dt>
|
||
<dd>Configure internal settings for a socket.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">bind</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">const</span> <span class="pre">struct</span> <span class="pre">sockaddr</span> <span class="pre">*address,</span> <span class="pre">socklen_t</span> <span class="pre">address_len);</span></code></dt>
|
||
<dd>Assign a local sockaddr to a socket identifier; returns negative values if the bind cannot be done.</dd>
|
||
</dl>
|
||
</div>
|
||
<p><a class="reference external" href="Sockets.html#cl4-8">Code Listing 4.8</a> demonstrates using <code class="docutils literal notranslate"><span class="pre">setsockopt()</span></code> and <code class="docutils literal notranslate"><span class="pre">bind()</span></code> to extend the <a class="reference external" href="Sockets.html#cl4-7">Code
|
||
Listing 4.7</a> to set up a TCP server. From <a class="reference external" href="Sockets.html#cl4-7">Code Listing 4.7</a>, the port number
|
||
requested for the server is 8000, which is the port number that would be stored in the <code class="docutils literal notranslate"><span class="pre">struct</span>
|
||
<span class="pre">sockaddr</span></code> passed to <code class="docutils literal notranslate"><span class="pre">bind()</span></code>. The call to <code class="docutils literal notranslate"><span class="pre">setsockopt()</span></code> sets the <code class="docutils literal notranslate"><span class="pre">SO_REUSEADDR</span></code> option to
|
||
true (1, stored in <code class="docutils literal notranslate"><span class="pre">socket_option</span></code>) at the socket level (<code class="docutils literal notranslate"><span class="pre">SOL_SOCKET</span></code>), meaning only this
|
||
particular socket is affected. If the <code class="docutils literal notranslate"><span class="pre">bind()</span></code> is successful, the server is established. Another
|
||
common option is <code class="docutils literal notranslate"><span class="pre">SO_RCVTIMEO</span></code>, which sets a time limit for blocking calls that read from the
|
||
socket, allowing the process to close lost connections.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-8"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30
|
||
31
|
||
32
|
||
33</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.8:</span>
|
||
<span class="cm"> Setting up a connection-oriented server and receiving connections</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Extending Code Listing 4.7 */</span>
|
||
<span class="kt">int</span> <span class="n">socket_option</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
|
||
<span class="k">for</span> <span class="p">(</span><span class="n">server</span> <span class="o">=</span> <span class="n">server_info</span><span class="p">;</span> <span class="n">server</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="n">server</span> <span class="o">=</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_next</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* Attempt to create a TCP socket */</span>
|
||
<span class="k">if</span> <span class="p">((</span><span class="n">socketfd</span> <span class="o">=</span> <span class="n">socket</span> <span class="p">(</span><span class="n">server</span><span class="o">-></span><span class="n">ai_family</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_socktype</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">continue</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Configure the socket to ignore bind reuse error */</span>
|
||
<span class="n">setsockopt</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">SO_REUSEADDR</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="p">)</span> <span class="o">&</span><span class="n">socket_option</span><span class="p">,</span>
|
||
<span class="k">sizeof</span> <span class="p">(</span><span class="kt">int</span><span class="p">));</span>
|
||
<span class="cm">/* Set a 5-second timeout when waiting to receive */</span>
|
||
<span class="k">struct</span> <span class="n">timeval</span> <span class="n">timeout</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span> <span class="p">};</span>
|
||
<span class="n">setsockopt</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">SO_RCVTIMEO</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="p">)</span> <span class="o">&</span><span class="n">timeout</span><span class="p">,</span>
|
||
<span class="k">sizeof</span> <span class="p">(</span><span class="n">timeout</span><span class="p">));</span>
|
||
|
||
<span class="cm">/* Bind the TCP socket to the port number */</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">bind</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addrlen</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">break</span><span class="p">;</span>
|
||
<span class="n">close</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">);</span>
|
||
<span class="n">socketfd</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="n">freeaddrinfo</span> <span class="p">(</span><span class="n">server_list</span><span class="p">);</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">socketfd</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="n">perror</span> <span class="p">(</span><span class="s">"ERROR: Failed to bind socket"</span><span class="p">);</span>
|
||
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<div class="figure mb-2 align-right" id="id14" style="width: 35%">
|
||
<span id="sockudptiming"></span><a class="reference internal image-reference" href="_images/CSF-Images.4.5.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Timing for a connection-less server that uses UDP" src="_images/CSF-Images.4.5.png" style="width: 90%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 4.4.12: Timing for a connection-less server that uses UDP</span></p>
|
||
</div>
|
||
<p>For connection-less protocols like UDP, no further action is needed to set up the server. The server
|
||
can immediately begin waiting on incoming messages from the socket. <a href="Sockets.html#sockudptiming">Figure 4.4.12</a>
|
||
illustrates the flow of the client and server functions calls for this scenario. Observe that
|
||
<code class="docutils literal notranslate"><span class="pre">connect()</span></code> does not transmit any message across the network and only updates local settings on
|
||
the client. To exchange data, the two processes would call <code class="docutils literal notranslate"><span class="pre">sendto()</span></code> and <code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code>, which
|
||
are explained in the next section.</p>
|
||
<p>Connection-oriented TCP sockets require two additional function calls. The first, <code class="docutils literal notranslate"><span class="pre">listen()</span></code>,
|
||
converts the socket to a connection-oriented server socket with a designated request queue. The
|
||
second parameter, <code class="docutils literal notranslate"><span class="pre">backlog</span></code>, can be used to modify the maximum number of enqueued connection
|
||
requests. Setting this value to 0 will use the system default size, which varies depending on the
|
||
system implementation of the C library. There is also a maximum allowable listen queue size, defined
|
||
by the constant <code class="docutils literal notranslate"><span class="pre">SOMAXCONN</span></code>. Once the process has converted its socket to a server socket,
|
||
repeated calls to <code class="docutils literal notranslate"><span class="pre">accept()</span></code> establish connections with incoming requests. The <code class="docutils literal notranslate"><span class="pre">accept()</span></code>
|
||
function is blocking, so the process will wait at that point until a new request comes in. When a
|
||
new request arrives, <code class="docutils literal notranslate"><span class="pre">accept()</span></code> performs the server side of the 3-way handshake to establish the
|
||
connection, storing information about the client in the <code class="docutils literal notranslate"><span class="pre">address</span></code> and <code class="docutils literal notranslate"><span class="pre">address_len</span></code> fields.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <sys/socket.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">listen</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">int</span> <span class="pre">backlog);</span></code></dt>
|
||
<dd>Convert the socket to a server socket that can accept incoming requests.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">accept</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">struct</span> <span class="pre">sockaddr</span> <span class="pre">*address,</span> <span class="pre">socklen_t</span> <span class="pre">*address_len);</span></code></dt>
|
||
<dd>Retrieve the first incoming connection, putting client’s information in the <code class="docutils literal notranslate"><span class="pre">sockaddr</span></code>.</dd>
|
||
</dl>
|
||
</div>
|
||
<div class="figure mb-2 align-right" id="id15" style="width: 35%">
|
||
<span id="socktcptiming"></span><a class="reference internal image-reference" href="_images/CSF-Images.4.6.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Timing for a connection-oriented server that uses UDP" src="_images/CSF-Images.4.6.png" style="width: 90%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 4.4.14: Timing for a connection-oriented server that uses UDP</span></p>
|
||
</div>
|
||
<p><a href="Sockets.html#socktcptiming">Figure 4.4.14</a> illustrates how the timing of the client and server functions relate.
|
||
Both processes independently set up their sockets. The server then executes the sequence of calling
|
||
<code class="docutils literal notranslate"><span class="pre">bind()</span></code>, <code class="docutils literal notranslate"><span class="pre">listen()</span></code>, and <code class="docutils literal notranslate"><span class="pre">accept()</span></code>. The call to <code class="docutils literal notranslate"><span class="pre">accept()</span></code> is blocking, so the server
|
||
would then wait until a connection request arrives. When the request arrives, <code class="docutils literal notranslate"><span class="pre">accept()</span></code> would
|
||
collect information about the client host and return. Contrast the functionality of <code class="docutils literal notranslate"><span class="pre">connect()</span></code>
|
||
shown here with that shown in <a href="Sockets.html#sockudptiming">Figure 4.4.12</a>. With TCP sockets, the client call to
|
||
<code class="docutils literal notranslate"><span class="pre">connect()</span></code> sends an initial message to the server to establish the connection.</p>
|
||
<p><a class="reference external" href="Sockets.html#cl4-9">Code Listing 4.9</a> shows the final steps of setting up a TCP connection-oriented server
|
||
and receiving requests, beginning with the call to <code class="docutils literal notranslate"><span class="pre">listen()</span></code>. After converting the socket to a
|
||
server socket, the process enters a loop waiting on incoming connection requests. When <code class="docutils literal notranslate"><span class="pre">accept()</span></code>
|
||
returns with a connection, the client’s IP address and port number are copied into the struct
|
||
sockaddr. Note that the client’s port number will not be 8000 in this case, which is the port number
|
||
chosen for this server. Instead, client sockets are assigned an <a class="reference internal" href="Glossary.html#term-ephemeral-port"><span class="xref std std-term">ephemeral port</span></a>, which is a
|
||
pseudo-randomly selected integer in the range 1024 - 65535, when they are being set up. In this
|
||
example, the server uses the <code class="docutils literal notranslate"><span class="pre">inet_ntoa()</span></code> and <code class="docutils literal notranslate"><span class="pre">ntohs()</span></code> utilities to print the client’s IP
|
||
address and port number, then immediately closes the connection and frees the resources. If the
|
||
client tries to read from or write to the socket at that point, the operation would fail and the
|
||
client would get an error message back.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-9"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30
|
||
31</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.9:</span>
|
||
<span class="cm"> Receiving TCP connections</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Extending Code Listing 4.7 and 4.8 */</span>
|
||
|
||
<span class="cm">/* Convert to server socket */</span>
|
||
<span class="n">listen</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Get the size of the sockaddr from getaddrinfo() results */</span>
|
||
<span class="kt">socklen_t</span> <span class="n">addrlen</span> <span class="o">=</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addrlen</span><span class="p">;</span>
|
||
|
||
<span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* Allocate space for the incoming address info and get it */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr</span> <span class="o">*</span><span class="n">address</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="kt">size_t</span><span class="p">)</span> <span class="n">addrlen</span><span class="p">);</span>
|
||
<span class="n">assert</span> <span class="p">(</span><span class="n">address</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">);</span>
|
||
|
||
<span class="kt">int</span> <span class="n">connection</span><span class="p">;</span>
|
||
<span class="k">if</span> <span class="p">((</span><span class="n">connection</span> <span class="o">=</span> <span class="n">accept</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="o">&</span><span class="n">addrlen</span><span class="p">))</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">break</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Print information about the connection and close it */</span>
|
||
<span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="o">*</span><span class="n">addr</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="o">*</span><span class="p">)</span><span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">;</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"Incoming request from %s:%"</span> <span class="n">PRI16d</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">inet_ntoa</span> <span class="p">(</span><span class="n">addr</span><span class="o">-></span><span class="n">sin_addr</span><span class="p">),</span>
|
||
<span class="n">ntohs</span> <span class="p">(</span><span class="n">addr</span><span class="o">-></span><span class="n">sin_port</span><span class="p">));</span>
|
||
|
||
<span class="n">close</span> <span class="p">(</span><span class="n">connection</span><span class="p">);</span>
|
||
<span class="n">free</span> <span class="p">(</span><span class="n">address</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
<span class="n">close</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">);</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="socket-communication">
|
||
<h2>4.4.4. Socket Communication<a class="headerlink" href="Sockets.html#socket-communication" title="Permalink to this headline">¶</a></h2>
|
||
<p>For TCP sockets, exchanging messages between the client and server can be done using the standard
|
||
<code class="docutils literal notranslate"><span class="pre">read()</span></code> and <code class="docutils literal notranslate"><span class="pre">write()</span></code> operations, as with other forms of IPC. This works because sockets are
|
||
treated like files, and the value returned from <code class="docutils literal notranslate"><span class="pre">socket()</span></code> behaves the same as any other file
|
||
descriptor. UDP sockets require the use of <code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code> and <code class="docutils literal notranslate"><span class="pre">sendto()</span></code> for data exchange. These
|
||
functions use <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">sockaddr</span></code> parameters to determine the sender’s IP address when receiving and
|
||
to specify the destination when sending. The <code class="docutils literal notranslate"><span class="pre">read()</span></code> and <code class="docutils literal notranslate"><span class="pre">write()</span></code> functions cannot serve this
|
||
purpose, as the UDP socket identified by the file descriptor does not store this information. The
|
||
<code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code> and <code class="docutils literal notranslate"><span class="pre">sendto()</span></code> functions can also be used by TCP for consistency.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">C library functions – <sys/socket.h></p><hr class="mt-1" />
|
||
<dl class="docutils">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">ssize_t</span> <span class="pre">recvfrom</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">void</span> <span class="pre">*buffer,</span> <span class="pre">size_t</span> <span class="pre">length,</span> <span class="pre">int</span> <span class="pre">flags,</span> <span class="pre">struct</span> <span class="pre">sockaddr</span> <span class="pre">*address,</span> <span class="pre">socklen_t</span> <span class="pre">*address_len);</span></code></dt>
|
||
<dd>Receive up to the given length in bytes from a socket.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">ssize_t</span> <span class="pre">sendto</span> <span class="pre">(int</span> <span class="pre">socket,</span> <span class="pre">const</span> <span class="pre">void</span> <span class="pre">*message,</span> <span class="pre">size_t</span> <span class="pre">length,</span> <span class="pre">int</span> <span class="pre">flags,</span> <span class="pre">const</span> <span class="pre">struct</span> <span class="pre">sockaddr</span> <span class="pre">*dest_addr,</span> <span class="pre">socklen_t</span> <span class="pre">dest_len);</span></code></dt>
|
||
<dd>Send a message to another host through a socket.</dd>
|
||
</dl>
|
||
</div>
|
||
<p>As with other socket-related functions, <code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code> and <code class="docutils literal notranslate"><span class="pre">sendto()</span></code> use the generic <code class="docutils literal notranslate"><span class="pre">struct</span>
|
||
<span class="pre">sockaddr</span></code> type, relying on the <code class="docutils literal notranslate"><span class="pre">socklen_t</span></code> parameter to determine its length and, indirectly, its
|
||
specific type. Both functions take a <code class="docutils literal notranslate"><span class="pre">void*</span></code> parameter and a size that define the location of the
|
||
bytes to send or to write received bytes. The <code class="docutils literal notranslate"><span class="pre">flags</span></code> parameter for each can specify advanced
|
||
usage options. <a class="reference external" href="Sockets.html#cl4-10">Code Listing 4.10</a> illustrates the use of these functions, sending a
|
||
simple HTTP request and reading the first part of the response.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl4-10"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 4.10:</span>
|
||
<span class="cm"> Sending to and receiving from an IPv6 socket</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Extending Code Listing 4.6 */</span>
|
||
|
||
<span class="cm">/* Create a message for a simple HTTP/1.0 request */</span>
|
||
<span class="kt">size_t</span> <span class="n">buffer_len</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="n">buffer_len</span><span class="p">];</span>
|
||
<span class="n">memset</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">buffer_len</span><span class="p">);</span>
|
||
<span class="n">strncpy</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">"GET / HTTP/1.0</span><span class="se">\r\n\r\n</span><span class="s">"</span><span class="p">,</span> <span class="n">buffer_len</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* When sending, you can check the number of bytes sent */</span>
|
||
<span class="kt">ssize_t</span> <span class="n">bytes</span> <span class="o">=</span>
|
||
<span class="n">sendto</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="n">buffer_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addrlen</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Copy the server IP address into a buffer */</span>
|
||
<span class="kt">char</span> <span class="n">addr_buffer</span><span class="p">[</span><span class="n">INET6_ADDRSTRLEN</span><span class="p">];</span>
|
||
<span class="n">inet_ntop</span> <span class="p">(</span><span class="n">AF_INET6</span><span class="p">,</span> <span class="o">&</span><span class="p">((</span><span class="k">struct</span> <span class="n">sockaddr_in6</span> <span class="o">*</span><span class="p">)</span><span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">)</span><span class="o">-></span><span class="n">sin6_addr</span><span class="p">,</span>
|
||
<span class="n">addr_buffer</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">addr_buffer</span><span class="p">));</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"Sent %zd bytes to %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">bytes</span><span class="p">,</span> <span class="n">addr_buffer</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Read all data into the buffer, keeping space for \0 at end */</span>
|
||
<span class="k">while</span> <span class="p">((</span><span class="n">bytes</span> <span class="o">=</span> <span class="n">recvfrom</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="n">buffer_len</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">server</span><span class="o">-></span><span class="n">ai_addr</span><span class="p">,</span>
|
||
<span class="o">&</span><span class="n">server</span><span class="o">-></span><span class="n">ai_addrlen</span><span class="p">))</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="n">printf</span> <span class="p">(</span><span class="s">"%s"</span><span class="p">,</span> <span class="n">buffer</span><span class="p">);</span>
|
||
<span class="n">memset</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">buffer_len</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
<span class="n">close</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">);</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p><a class="reference external" href="Sockets.html#cl4-10">Code Listing 4.10</a> assumes that a client socket has already been created and has
|
||
connected to a web server, as shown in <a class="reference external" href="Sockets.html#cl4-6">Code Listing 4.6</a>. For simplicity regarding the
|
||
call to <code class="docutils literal notranslate"><span class="pre">inet_ntop()</span></code>, we are assuming this socket uses an IPv6; this assumption is only needed to
|
||
print the IP address out. When receiving, since the client does not know the number of bytes total
|
||
that will be sent, the client enters a loop that repeatedly requests enough data to fill up the
|
||
buffer. Since <code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code> is a blocking call, the process will wait if there are delays in the
|
||
network. When the server is finished sending, <code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code> will return zero and the client will
|
||
exit the loop.</p>
|
||
<table class="docutils footnote" frame="void" id="f23" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="Sockets.html#id1">[1]</a></td><td>The <code class="docutils literal notranslate"><span class="pre">"_in"</span></code> part of <code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code> means “Internet,” not “input.” Relatedly, the field
|
||
names have been changed from <code class="docutils literal notranslate"><span class="pre">sa_</span></code> (<em>socket address</em>) to <code class="docutils literal notranslate"><span class="pre">sin_</span></code> (<em>Internet socket address</em>).
|
||
For IPv6, the name of the <code class="docutils literal notranslate"><span class="pre">struct</span></code> becomes <code class="docutils literal notranslate"><span class="pre">sockaddr_in6</span></code> and the field names begin with <code class="docutils literal notranslate"><span class="pre">sin6_</span></code>.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="docutils footnote" frame="void" id="f24" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="Sockets.html#id2">[2]</a></td><td>OS that are derived from BSD UNIX, including macOS, have an additional field in both
|
||
<code class="docutils literal notranslate"><span class="pre">sockaddr_in</span></code> and <code class="docutils literal notranslate"><span class="pre">sockaddr_in6</span></code> to specify the length of the <code class="docutils literal notranslate"><span class="pre">struct</span></code>. This field is omitted
|
||
from our discussion, as it is not universal.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div
|
||
id="InterfaceSumm"
|
||
class="embedContainer"
|
||
data-exer-name="InterfaceSumm"
|
||
data-long-name="Socket programming questions"
|
||
data-short-name="InterfaceSumm"
|
||
data-frame-src="../../../Exercises/Sockets/InterfaceSumm.html?selfLoggingEnabled=false&localMode=true&module=Sockets&JXOP-debug=true&JOP-lang=en&JXOP-code=java"
|
||
data-frame-width="950"
|
||
data-frame-height="550"
|
||
data-external="false"
|
||
data-points="1.0"
|
||
data-required="True"
|
||
data-showhide="show"
|
||
data-threshold="7"
|
||
data-type="ka"
|
||
data-exer-id="">
|
||
|
||
<div class="center">
|
||
<div id="InterfaceSumm_iframe"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<div class="mt-4 container center">
|
||
«  <a id="prevmod1" href="NetApps.html">4.3. Network Applications and Protocols</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod1" href="TCPSockets.html">4.5. TCP Socket Programming: HTTP</a>  »
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div class="row jmu-dark-purple-bg">
|
||
<div class="col-md-12">
|
||
<center>
|
||
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
|
||
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
|
||
</center>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||
</body>
|
||
</html> |