注意:这篇文章上次更新于1687天前,文章内容可能已经过时。
This article was last updated1687 days ago, the content may be outdated.
网络编程基础API
socket地址API
主机字节序和网络字节序
网络字节序采用大端存储,即低位存储高地址,在网络传输时需要考虑是否进行字节序转换。Linux提供以下4个函数用于主机字节序和网络字节序的转换。
Basic Network Programming APIs
Socket Address API
Host Byte Order and Network Byte Order
The network byte order uses big-endian storage, i.e., the low-order bits are stored at high addresses, so it is necessary to consider whether byte order conversion is needed during network transmission. Linux provides the following 4 functions for converting between host byte order and network byte order.
1 |
|
Their meanings are quite clear; for example, htonl means “host to network long”.
The long integer type is used to convert IP addresses, and the short integer type is used to convert port numbers.
Generic Socket Address
1 |
|
地址族或协议族的可选内容:


The optional values of the address family or protocol family:


由表5-2可见,14字节的sa_data根本无法完全容纳多数协议族的地址值。因此,Linux定义了下面这个新的通用socket地址结构体:
As can be seen from Table 5-2, the 14-byte sa_data is completely unable to hold the address values of most protocol families. Therefore, Linux defines the following new generic socket address structure:
1 |
|
This structure has enough space and is byte-aligned.
Dedicated Socket Addresses
- UNIX local protocol family or address family.
1 |
|
- IPv4协议族
- IPv4 protocol family
1 | struct sockaddr_in{ |
- IPv6协议族
- IPv6 protocol family
1 | struct sockaddr_in6{ |
所有专用socket地址(以及sockaddr_storage)类型的变量在实际使用时都需要转化为通用socket地址类型sockaddr(强制转换即可),因为所有socket编程接口使用的地址参数的类型都是sockaddr。
IP地址转换函数
Variables of all dedicated socket address types (as well as sockaddr_storage) need to be converted to the generic socket address type sockaddr when actually used (a forced cast is sufficient), because the address parameters used by all socket programming interfaces are of type sockaddr.
IP Address Conversion Functions
1 |
|
inet_addr函数将用点分十进制字符串表示的IPv4地址转化为用网络字节序整数表示的IPv4地址。它失败时返回INADDR_NONE。
inet_aton函数完成和inet_addr同样的功能,但是将转化结果存储于参数inp指向的地址结构中。它成功时返回1,失败则返回0。
inet_ntoa函数将用网络字节序整数表示的IPv4地址转化为用点分十进制字符串表示的IPv4地址。但需要注意的是,该函数内部用一个静态变量存储转化结果,函数的返回值指向该静态内存,因此inet_ntoa是不可重入的。
下面这对更新的函数也能完成和前面3个函数同样的功能,并且它们同时适用于IPv4地址和IPv6地址:
The inet_addr function converts an IPv4 address represented by a dotted-decimal string into an IPv4 address represented by a network byte order integer. It returns INADDR_NONE on failure.
The inet_aton function does the same job as inet_addr, but stores the conversion result in the address structure pointed to by the inp parameter. It returns 1 on success and 0 on failure.
The inet_ntoa function converts an IPv4 address represented by a network byte order integer into an IPv4 address represented by a dotted-decimal string. Note, however, that this function internally uses a static variable to store the conversion result, and the return value points to that static memory, so inet_ntoa is not reentrant.
The newer pair of functions below can also do the same job as the previous 3 functions, and they work for both IPv4 and IPv6 addresses:
1 |
|
inet_pton函数将用字符串表示的IP地址src(用点分十进制字符串表示的IPv4地址或用十六进制字符串表示的IPv6地址)转换成用网络字节序整数表示的IP地址,并把转换结果存储于dst指向的内存中。其中,af参数指定地址族,可以是AF_INET或者AF_INET6。inet_pton成功时返回1,失败则返回0并设置errno.
inet_ntop函数进行相反的转换,前三个参数的含义与inet_pton的参数相同,最后一个参数cnt指定目标存储单元的大小。下面的两个宏能帮助我们指定这个大小(分别用于IPv4和IPv6):
The inet_pton function converts an IP address src represented by a string (an IPv4 address in dotted-decimal notation or an IPv6 address in hexadecimal notation) into an IP address represented by a network byte order integer, and stores the conversion result in the memory pointed to by dst. Among them, the af parameter specifies the address family, which can be AF_INET or AF_INET6. On success, inet_pton returns 1; on failure it returns 0 and sets errno.
The inet_ntop function performs the reverse conversion. The meanings of the first three parameters are the same as those of inet_pton, and the last parameter cnt specifies the size of the target storage unit. The following two macros help us specify this size (for IPv4 and IPv6 respectively):
1 |
1 |
|
domain参数告诉系统使用哪个底层协议族。对TCP/IP协议族而言,该参数应该设置为PF_INET(Protocol Family of Internet,用于IPv4)或PF_INET6(用于IPv6);对于UNIX本地域协议族而言,该参数应该设置为PF_UNIX。关于socket系统调用支持的所有协议族,请读者自己参考其man手册。
type参数指定服务类型。服务类型主要有SOCK_STREAM服务(流服务)和SOCK_UGRAM(数据报)服务。对TCP/IP协议族而言,其值取SOCK_STREAM表示传输层使用TCP协议,取SOCK_DGRAM表示传输层使用UDP协议。
protocol参数是在前两个参数构成的协议集合下,再选择一个具体的协议。不过这个值通常都是唯一的(前两个参数已经完全决定了它的值)。几乎在所有情况下,我们都应该把它设置为0,表示使用默认协议。
命名socket
The domain parameter tells the system which underlying protocol family to use. For the TCP/IP protocol family, this parameter should be set to PF_INET (Protocol Family of Internet, for IPv4) or PF_INET6 (for IPv6); for the UNIX local domain protocol family, this parameter should be set to PF_UNIX. For all the protocol families supported by the socket system call, please refer to its man page yourself.
The type parameter specifies the service type. The main service types are SOCK_STREAM service (stream service) and SOCK_UGRAM (datagram service). For the TCP/IP protocol family, taking the value SOCK_STREAM means the transport layer uses TCP, and taking SOCK_DGRAM means the transport layer uses UDP.
The protocol parameter selects a specific protocol within the protocol set formed by the first two parameters. However, this value is usually unique (the first two parameters have already fully determined it). In almost all cases, we should set it to 0, meaning the default protocol is used.
Naming a Socket
1 |
|
bind将my_addr所指的socket地址分配给未命名的sockfd文件描述符,addrlen参数指出该socket地址的长度。
bind成功时返回0,失败则返回-1并设置errno。其中两种常见的errno是EACCES和EADDRINUSE,它们的含义分别是:
❑EACCES,被绑定的地址是受保护的地址,仅超级用户能够访问。比如普通用户将socket绑定到知名服务端口(端口号为0~1023)上时,bind将返回EACCES错误。
❑EADDRINUSE,被绑定的地址正在使用中。比如将socket绑定到一个处于TIME_WAIT状态的socket地址。
监听socket
bind assigns the socket address pointed to by my_addr to the unnamed sockfd file descriptor, and the addrlen parameter indicates the length of this socket address.
On success, bind returns 0; on failure it returns -1 and sets errno. Two common errno values are EACCES and EADDRINUSE, whose meanings are:
❑EACCES, the address to be bound is a protected address that only the superuser can access. For example, when an ordinary user binds a socket to a well-known service port (ports 0 to 1023), bind returns an EACCES error.
❑EADDRINUSE, the address to be bound is already in use. For example, binding a socket to a socket address in the TIME_WAIT state.
Listening on a Socket
1 |
|
sockfd参数指定被监听的socket。backlog参数提示内核监听队列的最大长度。监听队列的长度如果超过backlog,服务器将不受理新的客户连接,客户端也将收到ECONNREFUSED错误信息。在内核版本2.2之前的Linux中,backlog参数是指所有处于半连接状态(SYN_RCVD)和完全连接状态(ESTABLISHED)的socket的上限。但自内核版本2.2之后,它只表示处于完全连接状态的socket的上限,处于半连接状态的socket的上限则由/proc/sys/net/ipv4/tcp_max_syn_backlog内核参数定义。backlog参数的典型值是5。
listen成功时返回0,失败则返回-1并设置errno。
完整连接最多有(backlog+1)个。
接受连接
The sockfd parameter specifies the socket to be listened on. The backlog parameter suggests the maximum length of the kernel listening queue. If the length of the listening queue exceeds backlog, the server will not accept new client connections, and clients will also receive an ECONNREFUSED error. In Linux kernels before version 2.2, the backlog parameter was the upper limit for all sockets in the half-open state (SYN_RCVD) and the fully connected state (ESTABLISHED). But since kernel version 2.2, it only represents the upper limit for sockets in the fully connected state; the upper limit for sockets in the half-open state is defined by the kernel parameter /proc/sys/net/ipv4/tcp_max_syn_backlog. A typical value for the backlog parameter is 5.
On success, listen returns 0; on failure it returns -1 and sets errno.
There can be at most (backlog+1) fully established connections.
Accepting Connections
1 |
|
ckfd参数是执行过listen系统调用的监听socket 。addr参数用来获取被接受连接的远端socket地址,该socket地址的长度由addrlen参数指出。accept成功时返回一个新的连接socket,该socket唯一地标识了被接受的这个连接,服务器可通过读写该socket来与被接受连接对应的客户端通信。accept失败时返回-1并设置errno。
accept只是从监听队列中取出连接,而不论连接处于何种状态,更不关心任何网络状况的变化。
发起连接
The ckfd parameter is the listening socket that has executed the listen system call. The addr parameter is used to obtain the remote socket address of the accepted connection, and the length of this socket address is indicated by the addrlen parameter. On success, accept returns a new connection socket that uniquely identifies the accepted connection; the server can communicate with the client corresponding to the accepted connection by reading and writing this socket. On failure, accept returns -1 and sets errno.
accept only takes a connection out of the listening queue, regardless of the state of the connection, and pays no attention to any changes in network conditions.
Initiating a Connection
1 |
|
sockfd参数由socket系统调用返回一个socket。serv_addr参数是服务器监听的socket地址,addrlen参数则指定这个地址的长度。
connect成功时返回0。一旦成功建立连接,sockfd就唯一地标识了这个连接,客户端就可以通过读写sockfd来与服务器通信。connect失败则返回-1并设置errno。
关闭连接
关闭文件描述符。
The sockfd parameter is a socket returned by the socket system call. The serv_addr parameter is the socket address the server listens on, and the addrlen parameter specifies the length of this address.
On success, connect returns 0. Once the connection is successfully established, sockfd uniquely identifies this connection, and the client can communicate with the server by reading and writing sockfd. On failure, connect returns -1 and sets errno.
Closing a Connection
Closing a file descriptor.
1 |
|
fd参数是待关闭的socket。不过,close系统调用并非总是立即关闭一个连接,而是将fd的引用计数减1。只有当fd的引用计数为0时,才真正关闭连接。多进程程序中,一次fork系统调用默认将使父进程中打开的socket的引用计数加1,因此我们必须在父进程和子进程中都对该socket执行close调用才能将连接关闭。
如果无论如何都要立即终止连接(而不是将socket的引用计数减1),可以使用如下的shutdown系统调用(相对于close来说,它是专门为网络编程设计的):
The fd parameter is the socket to be closed. However, the close system call does not always close a connection immediately; instead, it decrements the reference count of fd by 1. Only when the reference count of fd reaches 0 is the connection actually closed. In multi-process programs, a fork system call by default increments the reference count of sockets opened in the parent process by 1, so we must call close on the socket in both the parent and child processes to close the connection.
If you must terminate the connection immediately (instead of decrementing the socket’s reference count by 1), you can use the following shutdown system call (compared with close, it is specifically designed for network programming):
1 |
|
sockfd参数是待关闭的socket。howto参数决定了shutdown的行为,它可取表5-3中的某个值。

由此可见,shutdown能够分别关闭socket上的读或写,或者都关闭。而close在关闭连接时只能将socket上的读和写同时关闭。
shutdown成功时返回0,失败则返回-1并设置errno。
数据读写
TCP 数据读写
对文件的读写操作read和write同样适用于socket。但是socket编程接口提供了几个专门用于socket数据读写的系统调用,它们增加了对数据读写的控制。其中用于TCP流数据读写的系统调用是:
The sockfd parameter is the socket to be closed. The howto parameter determines the behavior of shutdown; it can take one of the values in Table 5-3.

It can be seen that shutdown can close the read or write side of a socket separately, or both. While close can only close both reading and writing on a socket at the same time.
On success, shutdown returns 0; on failure it returns -1 and sets errno.
Data Reading and Writing
TCP Data Reading and Writing
The read and write operations for files also apply to sockets. However, the socket programming interface provides several system calls specifically for socket data reading and writing, which add more control over data I/O. The system calls used for TCP stream data reading and writing are:
1 |
|
recv读取sockfd上的数据,buf和len参数分别指定读缓冲区的位置和大小,flags参数的含义见后文,通常设置为0即可。recv成功时返回实际读取到的数据的长度,它可能小于我们期望的长度len。因此我们可能要多次调用recv,才能读取到完整的数据。recv可能返回0,这意味着通信对方已经关闭连接了。recv出错时返回-1并设置errno。
send往sockfd上写入数据,buf和len参数分别指定写缓冲区的位置和大小。send成功时返回实际写入的数据的长度,失败则返回-1并设置errno。
flags参数为数据收发提供了额外的控制,它可以取表5-4所示选项中的一个或几个的逻辑或。

值得一提的是,flags参数只对send和recv的当前调用生效,而后面我们将看到如何通过setsockopt系统调用永久性地修改socket的某些属性。
UDP数据读写
recv reads data on sockfd; the buf and len parameters specify the position and size of the read buffer respectively, and the meaning of the flags parameter is described later, usually set to 0. On success, recv returns the length of the data actually read, which may be smaller than the expected length len. Therefore, we may need to call recv multiple times to read the complete data. recv may return 0, which means the peer has closed the connection. On error, recv returns -1 and sets errno.
send writes data to sockfd; the buf and len parameters specify the position and size of the write buffer respectively. On success, send returns the length of the data actually written; on failure it returns -1 and sets errno.
The flags parameter provides additional control over data sending and receiving; it can take the logical OR of one or several options shown in Table 5-4.

It is worth mentioning that the flags parameter only takes effect for the current send/recv call; later we will see how to permanently modify certain attributes of a socket through the setsockopt system call.
UDP Data Reading and Writing
1 |
|
recvfrom读取sockfd上的数据,buf和len参数分别指定读缓冲区的位置和大小。因为UDP通信没有连接的概念,所以我们每次读取数据都需要获取发送端的socket地址,即参数src_addr所指的内容,addrlen参数则指定该地址的长度。
sendto往sockfd上写入数据,buf和len参数分别指定写缓冲区的位置和大小。dest_addr参数指定接收端的socket地址,addrlen参数则指定该地址的长度。
这两个系统调用的flags参数以及返回值的含义均与send/recv系统调用的flags参数及返回值相同。
值得一提的是,recvfrom/sendto系统调用也可以用于面向连接(STREAM)的socket的数据读写,只需要把最后两个参数都设置为NULL以忽略发送端/接收端的socket地址(因为我们已经和对方建立了连接,所以已经知道其socket地址了)。
带外标记
recvfrom reads data on sockfd; the buf and len parameters specify the position and size of the read buffer respectively. Since UDP communication has no concept of a connection, every time we read data we need to obtain the sender’s socket address, i.e., the content pointed to by the src_addr parameter, and the addrlen parameter specifies the length of that address.
sendto writes data to sockfd; the buf and len parameters specify the position and size of the write buffer respectively. The dest_addr parameter specifies the receiver’s socket address, and the addrlen parameter specifies the length of that address.
The meanings of the flags parameters and return values of these two system calls are the same as those of the send/recv system calls.
It is worth mentioning that the recvfrom/sendto system calls can also be used for data reading and writing on connection-oriented (STREAM) sockets; you only need to set the last two parameters to NULL to ignore the sender’s/receiver’s socket address (because we have already established a connection with the peer, we already know its socket address).
Out-of-Band Mark
1 |
|
sockatmark判断sockfd是否处于带外标记,即下一个被读取到的数据是否是带外数据。如果是,sockatmark返回1,此时我们就可以利用带MSG_OOB标志的recv调用来接收带外数据。如果不是,则sockatmark返回0。
地址信息函数
在某些情况下,我们想知道一个连接socket的本端socket地址,以及远端的socket地址。下面这两个函数正是用于解决这个问题:
sockatmark determines whether sockfd is at the out-of-band mark, i.e., whether the next data to be read is out-of-band data. If so, sockatmark returns 1, and at this point we can use a recv call with the MSG_OOB flag to receive the out-of-band data. If not, sockatmark returns 0.
Address Information Functions
In some cases, we want to know the local socket address of a connected socket, as well as the remote socket address. The following two functions are exactly for solving this problem:
1 |
|
getsockname获取sockfd对应的本端socket地址,并将其存储于address参数指定的内存中,该socket地址的长度则存储于address_len参数指向的变量中。如果实际socket地址的长度大于address所指内存区的大小,那么该socket地址将被截断。getsockname成功时返回0,失败返回-1并设置errno。
getpeername获取sockfd对应的远端socket地址,其参数及返回值的含义与getsockname的参数及返回值相同。
socket选项
getsockname obtains the local socket address corresponding to sockfd and stores it in the memory specified by the address parameter; the length of this socket address is stored in the variable pointed to by the address_len parameter. If the actual length of the socket address is greater than the size of the memory area pointed to by address, the socket address will be truncated. On success, getsockname returns 0; on failure it returns -1 and sets errno.
getpeername obtains the remote socket address corresponding to sockfd; the meanings of its parameters and return value are the same as those of getsockname.
Socket Options
1 |
|
sockfd参数指定被操作的目标socket。level参数指定要操作哪个协议的选项(即属性),比如IPv4、IPv6、TCP等。option_name参数则指定选项的名字。我们在表5-5中列举了socket通信中几个比较常用的socket选项。option_value和option_len参数分别是被操作选项的值和长度。不同的选项具有不同类型的值,如表5-5中“数据类型”一列所示。

getsockopt和setsockopt这两个函数成功时返回0,失败时返回-1并设置errno。
SO_RCVBUF和SO_SNDBUF选项分别表示TCP接收缓冲区和发送缓冲区的大小。不过,当我们用setsockopt来设置TCP的接收缓冲区和发送缓冲区的大小时,系统都会将其值加倍,并且不得小于某个最小值。TCP接收缓冲区的最小值是256字节,而发送缓冲区的最小值是2048字节(不过,不同的系统可能有不同的默认最小值)。系统这样做的目的,主要是确保一个TCP连接拥有足够的空闲缓冲区来处理拥塞(比如快速重传算法就期望TCP接收缓冲区能至少容纳4个大小为SMSS的TCP报文段)。此外,我们可以直接修改内核参数/proc/sys/net/ipv4/tcp_rmem和/proc/sys/net/ipv4/tcp_wmem来强制TCP接收缓冲区和发送缓冲区的大小没有最小值限制。
网络信息API
gethostbyname函数根据主机名称获取主机的完整信息,gethostbyaddr函数根据IP地址获取主机的完整信息。gethostbyname函数通常先在本地的/etc/hosts配置文件中查找主机,如果没有找到,再去访问DNS服务器。
The sockfd parameter specifies the target socket to operate on. The level parameter specifies which protocol’s options (i.e., attributes) to operate on, such as IPv4, IPv6, TCP, etc. The option_name parameter specifies the name of the option. In Table 5-5 we list several commonly used socket options in socket communication. The option_value and option_len parameters are respectively the value and length of the option being operated on. Different options have different types of values, as shown in the “Data Type” column of Table 5-5.

Both getsockopt and setsockopt return 0 on success and -1 on failure, setting errno.
The SO_RCVBUF and SO_SNDBUF options represent the sizes of the TCP receive buffer and send buffer respectively. However, when we use setsockopt to set the sizes of the TCP receive and send buffers, the system doubles the value and it must not be smaller than a certain minimum. The minimum value of the TCP receive buffer is 256 bytes, and the minimum value of the send buffer is 2048 bytes (though different systems may have different default minimums). The purpose of this is mainly to ensure that a TCP connection has enough free buffer to handle congestion (for example, the fast retransmit algorithm expects the TCP receive buffer to hold at least 4 TCP segments of size SMSS). In addition, we can directly modify the kernel parameters /proc/sys/net/ipv4/tcp_rmem and /proc/sys/net/ipv4/tcp_wmem to force the TCP receive and send buffer sizes to have no minimum limit.
Network Information APIs
The gethostbyname function obtains the complete information of a host by its host name, and the gethostbyaddr function obtains the complete information of a host by its IP address. The gethostbyname function usually first looks up the host in the local /etc/hosts configuration file; if it is not found, it then accesses the DNS server.
1 |
|
name参数指定目标主机的主机名,addr参数指定目标主机的IP地址,len参数指定addr所指IP地址的长度,type参数指定addr所指IP地址的类型,其合法取值包括AF_INET(用于IPv4地址)和AF_INET6(用于IPv6地址)。
这两个函数返回的都是hostent结构体类型的指针,hostent结构体的定义如下:
The name parameter specifies the host name of the target host; the addr parameter specifies the IP address of the target host; the len parameter specifies the length of the IP address pointed to by addr; the type parameter specifies the type of the IP address pointed to by addr, whose legal values include AF_INET (for IPv4 addresses) and AF_INET6 (for IPv6 addresses).
Both functions return a pointer to a hostent structure; the definition of the hostent structure is as follows:
1 |
|
getservbyname函数根据名称获取某个服务的完整信息,getservbyport函数根据端口号获取某个服务的完整信息。它们实际上都是通过读取/etc/services文件来获取服务的信息的。这两个函数的定义如下:
The getservbyname function obtains the complete information of a service by its name, and the getservbyport function obtains the complete information of a service by its port number. They actually obtain service information by reading the /etc/services file. The definitions of these two functions are as follows:
1 |
|
name参数指定目标服务的名字,port参数指定目标服务对应的端口号。proto参数指定服务类型,给它传递“tcp”表示获取流服务,给它传递“udp”表示获取数据报服务,给它传递NULL则表示获取所有类型的服务。
这两个函数返回的都是servent结构体类型的指针,结构体servent的定义如下:
The name parameter specifies the name of the target service, and the port parameter specifies the port number of the target service. The proto parameter specifies the service type; passing it “tcp” means obtaining stream services, passing it “udp” means obtaining datagram services, and passing it NULL means obtaining services of all types.
Both functions return a pointer to a servent structure; the definition of the servent structure is as follows:
1 |
|
需要指出的是,上面讨论的4个函数都是不可重入的,即非线程安全的。不过netdb.h头文件给出了它们的可重入版本。正如Linux下所有其他函数的可重入版本的命名规则那样,这些函数的函数名是在原函数名尾部加上_r(re-entrant)。
getaddrinfo函数既能通过主机名获得IP地址(内部使用的是gethostbyname函数),也能通过服务名获得端口号(内部使用的是getservbyname函数)。它是否可重入取决于其内部调用的gethostbyname和getservbyname函数是否是它们的可重入版本。该函数的定义如下:
It should be pointed out that the 4 functions discussed above are all non-reentrant, i.e., not thread-safe. However, the netdb.h header provides their reentrant versions. Following the naming convention of reentrant versions of all other functions under Linux, the names of these functions are formed by appending _r (re-entrant) to the original function names.
The getaddrinfo function can obtain an IP address through a host name (internally using the gethostbyname function), and can also obtain a port number through a service name (internally using the getservbyname function). Whether it is reentrant depends on whether the gethostbyname and getservbyname functions it calls internally are their reentrant versions. The definition of this function is as follows:
1 |
|
hostname参数可以接收主机名,也可以接收字符串表示的IP地址(IPv4采用点分十进制字符串,IPv6则采用十六进制字符串)。同样,service参数可以接收服务名,也可以接收字符串表示的十进制端口号。hints参数是应用程序给getaddrinfo的一个提示,以对getaddrinfo的输出进行更精确的控制。hints参数可以被设置为NULL,表示允许getaddrinfo反馈任何可用的结果。result参数指向一个链表,该链表用于存储getaddrinfo反馈的结果。
getnameinfo函数能通过socket地址同时获得以字符串表示的主机名(内部使用的是gethostbyaddr函数)和服务名(内部使用的是getservbyport函数)。它是否可重入取决于其内部调用的gethostbyaddr和getservbyport函数是否是它们的可重入版本。该函数的定义如下:
The hostname parameter can accept a host name, and can also accept an IP address represented as a string (IPv4 uses dotted-decimal strings, IPv6 uses hexadecimal strings). Likewise, the service parameter can accept a service name, and can also accept a decimal port number represented as a string. The hints parameter is a hint given by the application to getaddrinfo to control getaddrinfo’s output more precisely. The hints parameter can be set to NULL, meaning getaddrinfo is allowed to return any available results. The result parameter points to a linked list used to store the results returned by getaddrinfo.
The getnameinfo function can simultaneously obtain a host name represented as a string (internally using the gethostbyaddr function) and a service name (internally using the getservbyport function) from a socket address. Whether it is reentrant depends on whether the gethostbyaddr and getservbyport functions it calls internally are their reentrant versions. The definition of this function is as follows:
1 |
|


