嵌入式linux学习笔记–TCP通讯整理

之前的项目中使用到了比较多的tcp 通讯相关的知识,一直也没有进行整理,今天准备拿出时间好好的整理一下TCP通讯的整个过程。预计会整理linux和windows两个版本的tcp通讯的流程。

以下关于API的参数整理参考了 《unix环境高级编程》和 《Linux Programmer’s Manual》。 后面的其实就是我们的man 指令

1.TCP通讯的函数的介绍

1.1 int socket(int domain, int type, int protocol);

所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。 – 百度百科

domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等
protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。

这个函数的作用就是创建一个套接字。 如果成功就返回文件描述符,失败返回-1 并且 将错误信息保存在error .

int socket(int domain, int type, int protocol);
//创建用于通信的端点并返回引用该端点的文件描述符。
/* socket()  creates  an  endpoint for communication and returns a file descriptor that refers to that endpoint.  The file descriptor returned by a successful call will be the lowest-num‐
bered file descriptor not currently open for the process.
The domain argument specifies a communication domain;
this selects the protocol family which will be used for communication.
These families are defined in  <sys/socket.h>.  The  currently understood formats include:Name                Purpose                          Man pageAF_UNIX, AF_LOCAL   Local communication              unix(7)AF_INET             IPv4 Internet protocols          ip(7)     // 一般会用这个协议  也就是现在(2021 年仍然在广泛使用的IPV4协议)AF_INET6            IPv6 Internet protocols          ipv6(7)AF_IPX              IPX - Novell protocolsAF_NETLINK          Kernel user interface device     netlink(7)AF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)AF_AX25             Amateur radio AX.25 protocolAF_ATMPVC           Access to raw ATM PVCsAF_APPLETALK        AppleTalk                        ddp(7)AF_PACKET           Low level packet interface       packet(7)AF_ALG              Interface to kernel crypto API
The socket has the indicated type, which specifies the communication semantics.  Currently defined types are:SOCK_STREAM     Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mechanism may be supported.SOCK_DGRAM      Supports datagrams (connectionless, unreliable messages of a fixed maximum length).SOCK_SEQPACKET  Provides  a  sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length;a consumer is required to read an entire packetwith each input system call.SOCK_RAW        Provides raw network protocol access.SOCK_RDM        Provides a reliable datagram layer that does not guarantee ordering.SOCK_PACKET     Obsolete and should not be used in new programs; see packet(7).Some socket types may not be implemented by all protocol families.
return :
On success, a file descriptor for the new socket is returned.
On error, -1 is returned, and errno is set appropriately.
EACCES Permission to create a socket of the specified type and/or protocol is denied.
//  以下的 error 信息将可以从errno 查到EAFNOSUPPORTThe implementation does not support the specified address family.EINVAL Unknown protocol, or protocol family not available.EINVAL Invalid flags in type.EMFILE The per-process limit on the number of open file descriptors has been reached.ENFILE The system-wide limit on the total number of open files has been reached.ENOBUFS or ENOMEMInsufficient memory is available.  The socket cannot be created until sufficient resources are freed.EPROTONOSUPPORTThe protocol type or the specified protocol is not supported within this domain.Other errors may be generated by the underlying protocol modules.
*/

1.2 int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

服务器端要用 bind() 函数将套接字与特定的 IP 地址和端口绑定起来。这样指定端口收到的数据才会传递给这个套接字。

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
/*BIND(2)                                                                            Linux Programmer's Manual                                                                            BIND(2)NAMEbind - bind a name to a socketSYNOPSIS#include <sys/types.h>          #include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);DESCRIPTIONWhen  a  socket  is  created  with  socket(2), it exists in a name space (address family) but has no address assigned to it.  bind() assigns the address specified by addr to the socketreferred to by the file descriptor sockfd.  addrlen specifies the size, in bytes, of the address structure pointed to by addr.  Traditionally, this operation  is  called  “assigning  aname to a socket”.It is normally necessary to assign a local address using bind() before a SOCK_STREAM socket may receive connections (see accept(2)).The rules used in name binding vary between address families.  Consult the manual entries in Section 7 for detailed information.  For AF_INET, see ip(7); for AF_INET6, see ipv6(7); forAF_UNIX, see unix(7); for AF_APPLETALK, see ddp(7); for AF_PACKET, see packet(7); for AF_X25, see x25(7); and for AF_NETLINK, see netlink(7).The actual structure passed for the addr argument will depend on the address family.  The sockaddr structure is defined as something like:struct sockaddr {sa_family_t sa_family;char        sa_data[14];}The only purpose of this structure is to cast the structure pointer passed in addr in order to avoid compiler warnings.  See EXAMPLE below.RETURN VALUEOn success, zero is returned.  On error, -1 is returned, and errno is set appropriately.ERRORSEACCES The address is protected, and the user is not the superuser.EADDRINUSEThe given address is already in use.EADDRINUSE(Internet domain sockets) The port number was specified as zero in the socket address structure, but, upon attempting to bind to an ephemeral port, it was  determined  that  allport numbers in the ephemeral port range are currently in use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range ip(7).EBADF  sockfd is not a valid file descriptor.EINVAL The socket is already bound to an address.EINVAL addrlen is wrong, or addr is not a valid address for this socket's domain.ENOTSOCKThe file descriptor sockfd does not refer to a socket.The following errors are specific to UNIX domain (AF_UNIX) sockets:EACCES Search permission is denied on a component of the path prefix.  (See also path_resolution(7).)EADDRNOTAVAIL A nonexistent interface was requested or the requested address was not local.EFAULT addr points outside the user's accessible address space.ELOOP  Too many symbolic links were encountered in resolving addr.ENAMETOOLONGaddr is too long.ENOENT A component in the directory prefix of the socket pathname does not exist.ENOMEM Insufficient kernel memory was available.ENOTDIRA component of the path prefix is not a directory.EROFS  The socket inode would reside on a read-only filesystem.*/

1.3 int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

connect()用于建立与指定socket的连接。

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
/*
CONNECT(2)                                                                         Linux Programmer's Manual                                                                         CONNECT(2)NAMEconnect - initiate a connection on a socketSYNOPSIS#include <sys/types.h>       #include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);DESCRIPTIONThe  connect() system call connects the socket referred to by the file descriptor sockfd to the address specified by addr.  The addrlen argument specifies the size of addr.  The formatof the address in addr is determined by the address space of the socket sockfd; see socket(2) for further details.If the socket sockfd is of type SOCK_DGRAM, then addr is the address to which datagrams are sent by default, and the only address from which datagrams are received.  If the  socket  isof type SOCK_STREAM or SOCK_SEQPACKET, this call attempts to make a connection to the socket that is bound to the address specified by addr.Generally,  connection-based  protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change their association.  Con‐nectionless sockets may dissolve the association by connecting to an address with the sa_family member of sockaddr set to AF_UNSPEC (supported on Linux since kernel 2.2).RETURN VALUEIf the connection or binding succeeds, zero is returned.  On error, -1 is returned, and errno is set appropriately.ERRORSThe following are general socket errors only.  There may be other domain-specific error codes.EACCES For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket file, or search permission is denied for one of the directories in  the  pathprefix.  (See also path_resolution(7).)EACCES, EPERMThe user tried to connect to a broadcast address without having the socket broadcast flag enabled or the connection request failed because of a local firewall rule.EADDRINUSELocal address is already in use.EADDRNOTAVAIL(Internet  domain  sockets)  The socket referred to by sockfd had not previously been bound to an address and, upon attempting to bind it to an ephemeral port, it was determinedthat all port numbers in the ephemeral port range are currently in use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).EAFNOSUPPORTThe passed address didn't have the correct address family in its sa_family field.EAGAIN Insufficient entries in the routing cache.EALREADYThe socket is nonblocking and a previous connection attempt has not yet been completed.EBADF  sockfd is not a valid open file descriptor.ECONNREFUSEDA connect() on a stream socket found no one listening on the remote address.EFAULT The socket structure address is outside the user's address space.EINPROGRESS
The socket is nonblocking and the connection cannot be completed immediately.  It is possible to select(2) or poll(2) for completion by selecting the socket for writing.   Afterselect(2)  indicates  writability,  use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero) orunsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure).EINTR  The system call was interrupted by a signal that was caught; see signal(7).EISCONNThe socket is already connected.ENETUNREACHNetwork is unreachable.ENOTSOCKThe file descriptor sockfd does not refer to a socket.EPROTOTYPEThe socket type does not support the requested communications protocol.  This error can occur, for example, on an attempt to connect a UNIX domain datagram socket  to  a  streamsocket.ETIMEDOUTTimeout while attempting connection.  The server may be too busy to accept new connections.  Note that for IP sockets the timeout may be very long when syncookies are enabled onthe server.
*/

1.4 int listen(int sockfd, int backlog);

用listen()创建套接口并为申请进入的连接建立一个后备日志,然后便可用accept()接受连接了。

int listen(int sockfd, int backlog);
/*
LISTEN(2)                                                                          Linux Programmer's Manual                                                                          LISTEN(2)NAMElisten - listen for connections on a socketSYNOPSIS#include <sys/types.h>         #include <sys/socket.h>int listen(int sockfd, int backlog);DESCRIPTIONlisten() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept(2).The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM or SOCK_SEQPACKET.The  backlog  argument defines the maximum length to which the queue of pending connections for sockfd may grow.  If a connection request arrives when the queue is full, the client mayreceive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.RETURN VALUEOn success, zero is returned.  On error, -1 is returned, and errno is set appropriately.ERRORSEADDRINUSEAnother socket is already listening on the same port.EADDRINUSE(Internet domain sockets) The socket referred to by sockfd had not previously been bound to an address and, upon attempting to bind it to an ephemeral port,  it  was  determinedthat all port numbers in the ephemeral port range are currently in use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).EBADF  The argument sockfd is not a valid file descriptor.ENOTSOCKThe file descriptor sockfd does not refer to a socket.EOPNOTSUPPThe socket is not of a type that supports the listen() operation.
*/

1.5 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

套接口接受的一个连接。本函数从sockfd的等待连接队列中抽取第一个连接,创建一个与sockfd同类的新的套接口并返回句柄。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/*ACCEPT(2)                                                                          Linux Programmer's Manual                                                                          ACCEPT(2)NAMEaccept, accept4 - accept a connection on a socketSYNOPSIS#include <sys/types.h>           See NOTES #include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);#define _GNU_SOURCE              See feature_test_macros(7) #include <sys/socket.h>int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);DESCRIPTIONThe accept() system call is used with connection-based socket types (SOCK_STREAM, SOCK_SEQPACKET).  It extracts the first connection request on the queue of pending connections for thelistening socket, sockfd, creates a new connected socket, and returns a new file descriptor referring to that socket.  The newly created socket is not  in  the  listening  state.   Theoriginal socket sockfd is unaffected by this call.The argument sockfd is a socket that has been created with socket(2), bound to a local address with bind(2), and is listening for connections after a listen(2).The argument addr is a pointer to a sockaddr structure.  This structure is filled in with the address of the peer socket, as known to the communications layer.  The exact format of theaddress returned addr is determined by the socket's address family (see socket(2) and the respective protocol man pages).  When addr is NULL,  nothing  is  filled  in;  in  this  case,addrlen is not used, and should also be NULL.The  addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; on return it will contain the actualsize of the peer address.The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present.  If the socket is marked non‐blocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.In order to be notified of incoming connections on a socket, you can use select(2), poll(2), or epoll(7).  A readable event will be delivered when a new connection is attempted and youmay then call accept() to get a socket for that connection.  Alternatively, you can set the socket to deliver SIGIO when activity occurs on a socket; see socket(7) for details.If flags is 0, then accept4() is the same as accept().  The following values can be bitwise ORed in flags to obtain different behavior:SOCK_NONBLOCK   Set the O_NONBLOCK file status flag on the new open file description.  Using this flag saves extra calls to fcntl(2) to achieve the same result.SOCK_CLOEXEC    Set the close-on-exec (FD_CLOEXEC) flag on the new file descriptor.  See the description of the O_CLOEXEC flag in open(2) for reasons why this may be useful.RETURN VALUEOn success, these system calls return a nonnegative integer that is a file descriptor for the accepted socket.  On error, -1 is returned, and errno is set appropriately.Error handlingLinux accept() (and accept4()) passes already-pending network errors on the new socket as an error code from accept().  This behavior differs from  other  BSD  socket  implementations.For  reliable  operation  the application should detect the network errors defined for the protocol after accept() and treat them like EAGAIN by retrying.  In the case of TCP/IP, theseare ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH.
ERRORSEAGAIN or EWOULDBLOCKThe socket is marked nonblocking and no connections are present to be accepted.  POSIX.1-2001 and POSIX.1-2008 allow either error to be  returned  for  this  case,  and  do  notrequire these constants to have the same value, so a portable application should check for both possibilities.EBADF  sockfd is not an open file descriptor.ECONNABORTEDA connection has been aborted.EFAULT The addr argument is not in a writable part of the user address space.EINTR  The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7).EINVAL Socket is not listening for connections, or addrlen is invalid (e.g., is negative).EINVAL (accept4()) invalid value in flags.EMFILE The per-process limit on the number of open file descriptors has been reached.ENFILE The system-wide limit on the total number of open files has been reached.ENOBUFS, ENOMEMNot enough free memory.  This often means that the memory allocation is limited by the socket buffer limits, not by the system memory.ENOTSOCKThe file descriptor sockfd does not refer to a socket.EOPNOTSUPPThe referenced socket is not of type SOCK_STREAM.EPROTO Protocol error.In addition, Linux accept() may fail if:EPERM  Firewall rules forbid connection.In addition, network errors for the new socket and as defined for the protocol may be returned.  Various Linux kernels can return other errors such as ENOSR, ESOCKTNOSUPPORT, EPROTONO‐SUPPORT, ETIMEDOUT.  The value ERESTARTSYS may be seen during a trace.*/

1.6 数据发送的API send() sendto() sendmsg()

向一个已经连接的socket发送数据,不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。

/*SEND(2)                                                                            Linux Programmer's Manual                                                                            SEND(2)NAMEsend, sendto, sendmsg - send a message on a socketSYNOPSIS#include <sys/types.h>#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);DESCRIPTIONThe system calls send(), sendto(), and sendmsg() are used to transmit a message to another socket.The  send() call may be used only when the socket is in a connected state (so that the intended recipient is known).  The only difference between send() and write(2) is the presence offlags.  With a zero flags argument, send() is equivalent to write(2).  Also, the following callsend(sockfd, buf, len, flags);is equivalent tosendto(sockfd, buf, len, flags, NULL, 0);The argument sockfd is the file descriptor of the sending socket.If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) socket, the arguments dest_addr and addrlen are ignored (and the error EISCONN may be returned when they are  notNULL  and  0),  and  the  error ENOTCONN is returned when the socket was not actually connected.  Otherwise, the address of the target is given by dest_addr with addrlen specifying itssize.  For sendmsg(), the address of the target is given by msg.msg_name, with msg.msg_namelen specifying its size.For send() and sendto(), the message is found in buf and has length len.  For sendmsg(), the message is pointed to by the elements of the array msg.msg_iov.  The  sendmsg()  call  alsoallows sending ancillary data (also known as control information).If the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message is not transmitted.No indication of failure to deliver is implicit in a send().  Locally detected errors are indicated by a return value of -1.When  the message does not fit into the send buffer of the socket, send() normally blocks, unless the socket has been placed in nonblocking I/O mode.  In nonblocking mode it would failwith the error EAGAIN or EWOULDBLOCK in this case.  The select(2) call may be used to determine when it is possible to send more data.The flags argumentThe flags argument is the bitwise OR of zero or more of the following flags.MSG_CONFIRM (since Linux 2.3.15)Tell the link layer that forward progress happened: you got a successful reply from the other side.  If the link layer doesn't get this it will regularly  reprobe  the  neighbor(e.g., via a unicast ARP).  Valid only on SOCK_DGRAM and SOCK_RAW sockets and currently implemented only for IPv4 and IPv6.  See arp(7) for details.MSG_DONTROUTEDon't  use  a  gateway  to send out the packet, send to hosts only on directly connected networks.  This is usually used only by diagnostic or routing programs.  This is definedonly for protocol families that route; packet sockets don't.MSG_DONTWAIT (since Linux 2.2)Enables nonblocking operation; if the operation would block, EAGAIN or EWOULDBLOCK is returned.  This provides similar behavior to setting the O_NONBLOCK flag (via the  fcntl(2)F_SETFL  operation),  but  differs  in  that MSG_DONTWAIT is a per-call option, whereas O_NONBLOCK is a setting on the open file description (see open(2)), which will affect allthreads in the calling process and as well as other processes that hold file descriptors referring to the same open file description.MSG_EOR (since Linux 2.2)Terminates a record (when this notion is supported, as for sockets of type SOCK_SEQPACKET).MSG_MORE (since Linux 2.4.4)The caller has more data to send.  This flag is used with TCP sockets to obtain the same effect as the TCP_CORK socket option (see tcp(7)), with the difference  that  this  flagcan be set on a per-call basis.Since  Linux 2.6, this flag is also supported for UDP sockets, and informs the kernel to package all of the data sent in calls with this flag set into a single datagram which istransmitted only when a call is performed that does not specify this flag.  (See also the UDP_CORK socket option described in udp(7).)MSG_NOSIGNAL (since Linux 2.2)Don't generate a SIGPIPE signal if the peer on a stream-oriented socket has closed the connection.  The EPIPE error is still returned.  This provides similar behavior  to  usingsigaction(2) to ignore SIGPIPE, but, whereas MSG_NOSIGNAL is a per-call feature, ignoring SIGPIPE sets a process attribute that affects all threads in the process.MSG_OOBSends out-of-band data on sockets that support this notion (e.g., of type SOCK_STREAM); the underlying protocol must also support out-of-band data.sendmsg()The definition of the msghdr structure employed by sendmsg() is as follows:*/struct msghdr {void         *msg_name;       /* optional address */socklen_t     msg_namelen;    /* size of address */struct iovec *msg_iov;        /* scatter/gather array */size_t        msg_iovlen;     /* # elements in msg_iov */void         *msg_control;    /* ancillary data, see below */size_t        msg_controllen; /* ancillary data buffer len */int           msg_flags;      /* flags (unused) */};/* The  msg_name field is used on an unconnected socket to specify the target address for a datagram.  It points to a buffer containing the address; the msg_namelen field should be set tothe size of the address.  For a connected socket, these fields should be specified as NULL and 0, respectively.The msg_iov and msg_iovlen fields specify scatter-gather locations, as for writev(2).You may send control information using the msg_control and msg_controllen members.  The maximum control buffer length the kernel can process is limited  per  socket  by  the  value  in/proc/sys/net/core/optmem_max; see socket(7).The msg_flags field is ignored.
*/

1.7 数据接收指令recv() recvfrom() recvmsg()

不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;

RECV(2)                                                                            Linux Programmer's Manual                                                                            RECV(2)NAMErecv, recvfrom, recvmsg - receive a message from a socketSYNOPSIS#include <sys/types.h>#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);DESCRIPTIONThe  recv(), recvfrom(), and recvmsg() calls are used to receive messages from a socket.  They may be used to receive data on both connectionless and connection-oriented sockets.  Thispage first describes common features of all three system calls, and then describes the differences between the calls.The only difference between recv() and read(2) is the presence of flags.  With a zero flags argument, recv() is generally equivalent to read(2) (but see NOTES).   Also,  the  followingcallrecv(sockfd, buf, len, flags);is equivalent torecvfrom(sockfd, buf, len, flags, NULL, NULL);All  three calls return the length of the message on successful completion.  If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the typeof socket the message is received from.If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2)), in which case the value -1 is returned  andthe  external  variable errno is set to EAGAIN or EWOULDBLOCK.  The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of thefull amount requested.An application can use select(2), poll(2), or epoll(7) to determine when more data arrives on a socket.The flags argumentThe flags argument is formed by ORing one or more of the following values:MSG_CMSG_CLOEXEC (recvmsg() only; since Linux 2.6.23)Set the close-on-exec flag for the file descriptor received via a UNIX domain file descriptor using the SCM_RIGHTS operation (described in unix(7)).  This flag is useful for thesame reasons as the O_CLOEXEC flag of open(2).MSG_DONTWAIT (since Linux 2.2)Enables  nonblocking operation; if the operation would block, the call fails with the error EAGAIN or EWOULDBLOCK.  This provides similar behavior to setting the O_NONBLOCK flag(via the fcntl(2) F_SETFL operation), but differs in that MSG_DONTWAIT is a per-call option, whereas O_NONBLOCK is a setting on the open file description  (see  open(2)),  whichwill affect all threads in the calling process and as well as other processes that hold file descriptors referring to the same open file description.MSG_ERRQUEUE (since Linux 2.2)This  flag  specifies  that queued errors should be received from the socket error queue.  The error is passed in an ancillary message with a type dependent on the protocol (forIPv4 IP_RECVERR).  The user should supply a buffer of sufficient size.  See cmsg(3) and ip(7) for more information.  The payload of the original packet that caused the error  ispassed as normal data via msg_iovec.  The original destination address of the datagram that caused the error is supplied via msg_name.The error is supplied in a sock_extended_err structure:#define SO_EE_ORIGIN_NONE    0#define SO_EE_ORIGIN_LOCAL   1#define SO_EE_ORIGIN_ICMP    2#define SO_EE_ORIGIN_ICMP6   3struct sock_extended_err{uint32_t ee_errno;   /* error number */uint8_t  ee_origin;  /* where the error originated */uint8_t  ee_type;    /* type */uint8_t  ee_code;    /* code */uint8_t  ee_pad;     /* padding */uint32_t ee_info;    /* additional information */uint32_t ee_data;    /* other data *//* More data may follow */};struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);ee_errno  contains  the  errno  number  of  the  queued  error.   ee_origin is the origin code of where the error originated.  The other fields are protocol-specific.  The macroSOCK_EE_OFFENDER returns a pointer to the address of the network object where the error originated from given a pointer to the ancillary message.  If this address is not  known,the  sa_family member of the sockaddr contains AF_UNSPEC and the other fields of the sockaddr are undefined.  The payload of the packet that caused the error is passed as normaldata.For local errors, no address is passed (this can be checked with the cmsg_len member of the cmsghdr).  For error receives, the MSG_ERRQUEUE flag is set in the msghdr.  After  anerror has been passed, the pending socket error is regenerated based on the next queued error and will be passed on the next socket operation.MSG_OOBThis  flag  requests receipt of out-of-band data that would not be received in the normal data stream.  Some protocols place expedited data at the head of the normal data queue,and thus this flag cannot be used with such protocols.MSG_PEEKThis flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue.  Thus, a subsequent  receive  call  willreturn the same data.MSG_TRUNC (since Linux 2.2)For  raw  (AF_PACKET),  Internet  datagram  (since  Linux 2.4.27/2.6.8), netlink (since Linux 2.6.22), and UNIX datagram (since Linux 3.4) sockets: return the real length of thepacket or datagram, even when it was longer than the passed buffer.For use with Internet stream sockets, see tcp(7).MSG_WAITALL (since Linux 2.2)This flag requests that the operation block until the full request is satisfied.  However, the call may still return less data than requested if a signal is caught, an error  ordisconnect occurs, or the next data to be received is of a different type than that returned.  This flag has no effect for datagram sockets.recvfrom()recvfrom() places the received message into the buffer buf.  The caller must specify the size of the buffer in len.If  src_addr  is  not  NULL,  and the underlying protocol provides the source address of the message, that source address is placed in the buffer pointed to by src_addr.  In this case,addrlen is a value-result argument.  Before the call, it should be initialized to the size of the buffer associated with src_addr.  Upon return,  addrlen  is  updated  to  contain  theactual  size  of  the source address.  The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to thecall.If the caller is not interested in the source address, src_addr and addrlen should be specified as NULL.recv()The recv() call is normally used only on a connected socket (see connect(2)).  It is equivalent to the call:recvfrom(fd, buf, len, flags, NULL, 0);recvmsg()The recvmsg() call uses a msghdr structure to minimize the number of directly supplied arguments.  This structure is defined as follows in <sys/socket.h>:struct iovec {                    /* Scatter/gather array items */void  *iov_base;              /* Starting address */size_t iov_len;               /* Number of bytes to transfer */};struct msghdr {void         *msg_name;       /* optional address */socklen_t     msg_namelen;    /* size of address */struct iovec *msg_iov;        /* scatter/gather array */size_t        msg_iovlen;     /* # elements in msg_iov */void         *msg_control;    /* ancillary data, see below */size_t        msg_controllen; /* ancillary data buffer len */int           msg_flags;      /* flags on received message */};The msg_name field points to a caller-allocated buffer that is used to return the source address if the socket is unconnected.  The caller should set msg_namelen to the  size  of  thisbuffer  before this call; upon return from a successful call, msg_namelen will contain the length of the returned address.  If the application does not need to know the source address,msg_name can be specified as NULL.The fields msg_iov and msg_iovlen describe scatter-gather locations, as discussed in readv(2).The field msg_control, which has length msg_controllen, points to a buffer for other protocol control-related messages or miscellaneous  ancillary  data.   When  recvmsg()  is  called,msg_controllen should contain the length of the available buffer in msg_control; upon return from a successful call it will contain the length of the control message sequence.The messages are of the form:struct cmsghdr {size_t cmsg_len;    /* Data byte count, including header(type is socklen_t in POSIX) */int    cmsg_level;  /* Originating protocol */int    cmsg_type;   /* Protocol-specific type *//* followed byunsigned char cmsg_data[]; */};Ancillary data should be accessed only by the macros defined in cmsg(3).As an example, Linux uses this ancillary data mechanism to pass extended errors, IP options, or file descriptors over UNIX domain sockets.The msg_flags field in the msghdr is set on return of recvmsg().  It can contain several flags:MSG_EORindicates end-of-record; the data returned completed a record (generally used with sockets of type SOCK_SEQPACKET).MSG_TRUNCindicates that the trailing portion of a datagram was discarded because the datagram was larger than the buffer supplied.MSG_CTRUNCindicates that some control data were discarded due to lack of space in the buffer for ancillary data.MSG_OOBis returned to indicate that expedited or out-of-band data were received.MSG_ERRQUEUEindicates that no data was received but an extended error from the socket error queue.
RETURN VALUEThese calls return the number of bytes received, or -1 if an error occurred.  In the event of an error, errno is set to indicate the error.When a stream socket peer has performed an orderly shutdown, the return value will be 0 (the traditional "end-of-file" return).Datagram sockets in various domains (e.g., the UNIX and Internet domains) permit zero-length datagrams.  When such a datagram is received, the return value is 0.The value 0 may also be returned if the requested number of bytes to receive from a stream socket was 0.ERRORSThese are some standard errors generated by the socket layer.  Additional errors may be generated and returned from the underlying protocol modules; see their manual pages.EAGAIN or EWOULDBLOCKThe  socket  is  marked  nonblocking  and  the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.  POSIX.1 allowseither error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.EBADF  The argument sockfd is an invalid file descriptor.ECONNREFUSEDA remote host refused to allow the network connection (typically because it is not running the requested service).EFAULT The receive buffer pointer(s) point outside the process's address space.EINTR  The receive was interrupted by delivery of a signal before any data were available; see signal(7).EINVAL Invalid argument passed.ENOMEM Could not allocate memory for recvmsg().ENOTCONNThe socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).ENOTSOCKThe file descriptor sockfd does not refer to a socket.

1.8 可选参数的设置与获取API getsockopt, setsockopt

setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作,诸如加急数据是否在普通数据流中接收,广播数据是否可以从套接口发送等等。

getsockopt()函数用于获取任意类型、任意状态套接口的选项当前值,并把结果存入optval。在不同协议层上存在选项,但往往是在最高的“套接口”层次上,设置选项影响套接口的操作,诸如操作的阻塞与否、包的选径方式、带外数据的传送等。

GETSOCKOPT(2)                                                                      Linux Programmer's Manual                                                                      GETSOCKOPT(2)NAMEgetsockopt, setsockopt - get and set options on socketsSYNOPSIS#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);DESCRIPTIONgetsockopt()  and  setsockopt()  manipulate options for the socket referred to by the file descriptor sockfd.  Options may exist at multiple protocol levels; they are always present atthe uppermost socket level.When manipulating socket options, the level at which the option resides and the name of the option must be specified.  To manipulate options at the sockets API level, level  is  speci‐fied  as  SOL_SOCKET.   To  manipulate  options at any other level the protocol number of the appropriate protocol controlling the option is supplied.  For example, to indicate that anoption is to be interpreted by the TCP protocol, level should be set to the protocol number of TCP; see getprotoent(3).The arguments optval and optlen are used to access option values for setsockopt().  For getsockopt() they identify a buffer in which the value for the requested  option(s)  are  to  bereturned.   For getsockopt(), optlen is a value-result argument, initially containing the size of the buffer pointed to by optval, and modified on return to indicate the actual size ofthe value returned.  If no option value is to be supplied or returned, optval may be NULL.Optname and any specified options are passed uninterpreted to the appropriate protocol module for interpretation.  The include file <sys/socket.h> contains definitions for socket leveloptions, described below.  Options at other protocol levels vary in format and name; consult the appropriate entries in section 4 of the manual.Most socket-level options utilize an int argument for optval.  For setsockopt(), the argument should be nonzero to enable a boolean option, or zero if the option is to be disabled.For a description of the available socket options see socket(7) and the appropriate protocol man pages.RETURN VALUEOn success, zero is returned for the standard options.  On error, -1 is returned, and errno is set appropriately.Netfilter allows the programmer to define custom socket options with associated handlers; for such options, the return value on success is the value returned by the handler.ERRORSEBADF     The argument sockfd is not a valid file descriptor.EFAULT    The  address  pointed to by optval is not in a valid part of the process address space.  For getsockopt(), this error may also be returned if optlen is not in a valid part ofthe process address space.EINVAL    optlen invalid in setsockopt().  In some cases this error can also occur for an invalid value in optval (e.g., for the IP_ADD_MEMBERSHIP option described in ip(7)).ENOPROTOOPTThe option is unknown at the level indicated.ENOTSOCK  The file descriptor sockfd does not refer to a socket.

2. TCP 通讯流程的介绍

TCP的建立连接需要使用三次握手,TCP断开连接需要进行四次挥手。 这一部分我就不去班门弄斧了,网上大佬们说的也都很清楚

https://baijiahao.baidu.com/s?id=1654225744653405133&wfr=spider&for=pc

关于编程方面 windows 和linux 略有不同 先以linux 版本为例子(懒得写了,直接从网上找的例子)

2.1 linux 版本的服务端demo

// 以下程序是linux 版本的  服务端的程序 ,当调试软件连接上去之后就会收到服务器下发的信息
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>int main(){//创建套接字int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//将套接字和IP、端口绑定struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充serv_addr.sin_family = AF_INET;  //使用IPv4地址serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址serv_addr.sin_port = htons(1234);  //端口bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//进入监听状态,等待用户发起请求listen(serv_sock, 20);//接收客户端请求struct sockaddr_in clnt_addr;socklen_t clnt_addr_size = sizeof(clnt_addr);int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);//向客户端发送数据char str[] = "http://c.biancheng.net/socket/";write(clnt_sock, str, sizeof(str));//关闭套接字close(clnt_sock);close(serv_sock);return 0;
}

2.2 linux 版本的客户端demo

// https://www.cnblogs.com/rain24/archive/2011/11/18/2254455.html
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include <cstdlib>
#define PORT 1234#define MAXDATASIZE 100 //数据缓冲区最大长度int main(int argc, char *argv[])
{int sockfd, num;//数据缓冲区char buf[MAXDATASIZE];struct hostent *he;//服务器IPv4地址信息struct sockaddr_in server;if(argc != 2){printf("Usage: %s <IP Address>\n", argv[0]);exit(1);}//通过gethostbyname()得到服务端的主机信息if((he = gethostbyname(argv[1])) == NULL){printf("gethostbyname() error\n");exit(1);}//使用socket()创建套接字if((sockfd= socket(AF_INET, SOCK_STREAM, 0)) == -1){printf("socket() error\n");exit(1);}//初始化server地址信息bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(PORT);server.sin_addr = *((struct in_addr *)he->h_addr);//使用connect()函数来配置套接字,建立一个与TCP服务器的连接if(connect(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1){printf("connect() error\n");exit(1);}//使用recv()函数接收服务器发送的信息if((num = recv(sockfd, buf, MAXDATASIZE, 0)) == -1){printf("recv() error\n");exit(1);}buf[num - 1] = '\0';printf("server message: %s\n", buf);//关闭连接close(sockfd);return 0;
}

2.3 linux 版本的编译运行过程

root@jeason:~/work/ipc/socket# vi server.cpp
root@jeason:~/work/ipc/socket# g++ server.cpp -o server
root@jeason:~/work/ipc/socket# vi client.cpp
root@jeason:~/work/ipc/socket# g++ client.cpp -o client
root@jeason:~/work/ipc/socket# ls
client  client.cpp  server  server.cpp
root@jeason:~/work/ipc/socket# ls
client  client.cpp  server  server.cpp
root@jeason:~/work/ipc/socket# ./server &
[1] 10557
root@jeason:~/work/ipc/socket# ./client "127.0.0.1"
server message: http://c.biancheng.net/socket/
[1]+  Done                    ./server
root@jeason:~/work/ipc/socket#

2.4 windows 版本的服务端demo

// windows 版本的server 端程序
//版权声明:本文为CSDN博主「guo8113」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/guo8113/article/details/26448011
#include <winsock2.h>
#include <iostream>#include <string.h>
using namespace std;#pragma comment(lib, "ws2_32.lib")            //add ws2_32.libconst int DEFAULT_PORT = 8000;
int main(int argc,char* argv[])
{WORD   wVersionRequested;WSADATA wsaData;int       err,iLen;wVersionRequested  =  MAKEWORD(2,2);//create 16bit data
//(1)Load WinSockerr    =  WSAStartup(wVersionRequested,&wsaData); //load win socketif(err!=0){cout<<"Load WinSock Failed!";return -1;}
//(2)create socketSOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);if(sockSrv == INVALID_SOCKET){cout<<"socket() fail:"<<WSAGetLastError()<<endl;return -2;}
//(3)server IPSOCKADDR_IN addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);//Auto IP, byte sequence changeaddrSrv.sin_port = htons(DEFAULT_PORT);
//(4)binderr = bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));if(err!=0){cout<<"bind()fail"<<WSAGetLastError()<<endl;return -3;}//
//(5)listenerr = listen(sockSrv,5);if(err!=0){cout<<"listen()fail"<<WSAGetLastError()<<endl;return -4;}cout<<"Server waitting...:"<<endl;
//(6)client ipSOCKADDR_IN addrClt;int len = sizeof(SOCKADDR);while(1){//(7)acceptSOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClt,&len);char sendBuf[1024],hostname[100];if(gethostname(hostname,100)!=0)   //get host namestrcpy(hostname,"None");sprintf(sendBuf,"Welecome %s connected to %s!",inet_ntoa(addrClt.sin_addr),hostname);
//(8)send recverr = send(sockConn,sendBuf,strlen(sendBuf)+1,0);char recvBuf[1024]="\0";iLen = recv(sockConn,recvBuf,1024,0);recvBuf[iLen]='\0';cout <<recvBuf<<endl;
//(9)close connected sockclosesocket(sockConn);}
//(10)close server sockclosesocket(sockSrv);
//(11)clean up winsockWSACleanup();return 0;
}

2.5 windows 版本的客户端demo

// windows 版本的client 程序
//版权声明:本文为CSDN博主「guo8113」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/guo8113/article/details/26448011
#include <winsock2.h>
#include <iostream>#include <string.h>
using namespace std;#pragma comment(lib, "ws2_32.lib")            //add ws2_32.libconst int DEFAULT_PORT = 8000;
int main(int argc,char* argv[])
{WORD   wVersionRequested;WSADATA wsaData;int       err,iLen;wVersionRequested  =  MAKEWORD(2,2);//create 16bit data//(1)Load WinSockerr   =  WSAStartup(wVersionRequested,&wsaData); //load win socketif(err!=0){cout<<"Load WinSock Failed!";return -1;}//(2)create socketSOCKET sockClt = socket(AF_INET,SOCK_STREAM,0);if(sockClt == INVALID_SOCKET){cout<<"socket() fail:"<<WSAGetLastError()<<endl;return -2;}//(3)IPSOCKADDR_IN addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");addrSrv.sin_port = htons(DEFAULT_PORT);//(5)connecterr = connect(sockClt,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));if(err ==INVALID_SOCKET){cout<<"connect() fail"<<WSAGetLastError()<<endl;return -1;}char sendBuf[1024],hostname[100];if(gethostname(hostname,100)!=0)    //get host namestrcpy(hostname,"None");strcpy(sendBuf,hostname);strcat(sendBuf,"have connected to you!");err = send(sockClt,sendBuf,strlen(sendBuf)+1,0);char recvBuf[1024]="\0";iLen = recv(sockClt,recvBuf,1024,0);if(iLen ==0)return -3;else if(iLen==SOCKET_ERROR){cout<<"recv() fail:"<<WSAGetLastError()<<endl;return -4;}else{recvBuf[iLen] = '\0';cout<<recvBuf<<endl;}closesocket(sockClt);WSACleanup();system("PAUSE");return 0;
}

2.6 windows版本的编译运行过程

windows下使用的是cmake + mingw 进行编译

# 对应的cmake 编译文件
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
# Set project information
project(message_queue VERSION 1.0.0 LANGUAGES CXX)# 选择编程语言
add_executable(server server.cpp)      # 编译文件
add_executable(client client.cpp)      # 编译文件
target_link_libraries(server ws2_32)   # 链接socket 库
target_link_libraries(client ws2_32)   # 链接socket 库

对应的编译过程

C:\Users\Administrator\Desktop\windows_socket>cd build
C:\Users\Administrator\Desktop\windows_socket\build>cmake -G "MinGW Makefiles" ..
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/Administrator/Desktop/windows_socket/buildC:\Users\Administrator\Desktop\windows_socket\build>cd Desktop/windows_socketC:\Users\Administrator\Desktop\windows_socket\build>mingw32-make
"C:\Program Files\CMake\bin\cmake.exe" -SC:\Users\Administrator\Desktop\windows_socket -BC:\Users\Administrator\Desktop\windows_socket\build --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start C:\Users\Administrator\Desktop\windows_socket\build\CMakeFiles C:\Users\Administrator\Desktop\windows_socket\build\\CMakeFiles\progress.marks
mingw32-make -s -f CMakeFiles\Makefile2 all
[ 50%] Built target server
[100%] Built target client
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start C:\Users\Administrator\Desktop\windows_socket\build\CMakeFiles 0C:\Users\Administrator\Desktop\windows_socket\build>

windows 下客户端和服务端程序运行效果如下

3. 其余一些API的介绍

打开linux 系统下的文件 /usr/include/sys/socket.h

3.1 通用API

对应的函数的介绍 就参考英文介绍吧。 这里面比较重要的就是这个 sockatmark() 这个是发送紧急的TCP 数据包才会使用的。

/* Declarations of socket constants, types, and functions.Copyright (C) 1991-2018 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with the GNU C Library; if not, see<http://www.gnu.org/licenses/>.  */#ifndef _SYS_SOCKET_H
#define _SYS_SOCKET_H   1#include <features.h>__BEGIN_DECLS#include <bits/types/struct_iovec.h>
#define __need_size_t
#include <stddef.h>/* This operating system-specific header file defines the SOCK_*, PF_*,AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr',`struct msghdr', and `struct linger' types.  */
#include <bits/socket.h>#ifdef __USE_MISC
# include <bits/types/struct_osockaddr.h>
#endif/* The following constants should be used for the second parameter of`shutdown'.  */
enum
{SHUT_RD = 0,          /* No more receptions.  */
#define SHUT_RD         SHUT_RDSHUT_WR,              /* No more transmissions.  */
#define SHUT_WR         SHUT_WRSHUT_RDWR             /* No more receptions or transmissions.  */
#define SHUT_RDWR       SHUT_RDWR
};/* This is the type we use for generic socket address arguments.With GCC 2.7 and later, the funky union causes redeclarations oruses with any of the listed types to be allowed without complaint.G++ 2.7 does not support transparent unions so there we want theold-style declaration, too.  */
#if defined __cplusplus || !__GNUC_PREREQ (2, 7) || !defined __USE_GNU
# define __SOCKADDR_ARG         struct sockaddr *__restrict
# define __CONST_SOCKADDR_ARG   const struct sockaddr *
#else
/* Add more `struct sockaddr_AF' types here as necessary.These are all the ones I found on NetBSD and Linux.  */
# define __SOCKADDR_ALLTYPES \__SOCKADDR_ONETYPE (sockaddr) \__SOCKADDR_ONETYPE (sockaddr_at) \__SOCKADDR_ONETYPE (sockaddr_ax25) \__SOCKADDR_ONETYPE (sockaddr_dl) \__SOCKADDR_ONETYPE (sockaddr_eon) \__SOCKADDR_ONETYPE (sockaddr_in) \__SOCKADDR_ONETYPE (sockaddr_in6) \__SOCKADDR_ONETYPE (sockaddr_inarp) \__SOCKADDR_ONETYPE (sockaddr_ipx) \__SOCKADDR_ONETYPE (sockaddr_iso) \__SOCKADDR_ONETYPE (sockaddr_ns) \__SOCKADDR_ONETYPE (sockaddr_un) \__SOCKADDR_ONETYPE (sockaddr_x25)# define __SOCKADDR_ONETYPE(type) struct type *__restrict __##type##__;
typedef union { __SOCKADDR_ALLTYPES} __SOCKADDR_ARG __attribute__ ((__transparent_union__));
# undef __SOCKADDR_ONETYPE
# define __SOCKADDR_ONETYPE(type) const struct type *__restrict __##type##__;
typedef union { __SOCKADDR_ALLTYPES} __CONST_SOCKADDR_ARG __attribute__ ((__transparent_union__));
# undef __SOCKADDR_ONETYPE
#endif#ifdef __USE_GNU
/* For `recvmmsg' and `sendmmsg'.  */
struct mmsghdr{struct msghdr msg_hdr;      /* Actual message header.  */unsigned int msg_len;       /* Number of received or sent bytes for theentry.  */};
#endif/* Create a new socket of type TYPE in domain DOMAIN, usingprotocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.Returns a file descriptor for the new socket, or -1 for errors.  */
extern int socket (int __domain, int __type, int __protocol) __THROW;/* Create two new sockets, of type TYPE in domain DOMAIN and usingprotocol PROTOCOL, which are connected to each other, and put filedescriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,one will be chosen automatically.  Returns 0 on success, -1 for errors.  */
extern int socketpair (int __domain, int __type, int __protocol,int __fds[2]) __THROW;/* Give the socket FD the local address ADDR (which is LEN bytes long).  */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)__THROW;/* Put the local address of FD into *ADDR and its length in *LEN.  */
extern int getsockname (int __fd, __SOCKADDR_ARG __addr,socklen_t *__restrict __len) __THROW;/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).For connectionless socket types, just set the default address to send toand the only address from which to accept transmissions.Return 0 on success, -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);/* Put the address of the peer connected to socket FD into *ADDR(which is *LEN bytes long), and its actual length into *LEN.  */
extern int getpeername (int __fd, __SOCKADDR_ARG __addr,socklen_t *__restrict __len) __THROW;/* Send N bytes of BUF to socket FD.  Returns the number sent or -1.This function is a cancellation point and therefore not marked with__THROW.  */
extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);/* Read N bytes into BUF from socket FD.Returns the number read or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);/* Send N bytes of BUF on socket FD to peer at address ADDR (which isADDR_LEN bytes long).  Returns the number sent, or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern ssize_t sendto (int __fd, const void *__buf, size_t __n,int __flags, __CONST_SOCKADDR_ARG __addr,socklen_t __addr_len);/* Read N bytes into BUF through socket FD.If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address ofthe sender, and store the actual size of the address in *ADDR_LEN.Returns the number of bytes read or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,int __flags, __SOCKADDR_ARG __addr,socklen_t *__restrict __addr_len);/* Send a message described MESSAGE on socket FD.Returns the number of bytes sent, or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern ssize_t sendmsg (int __fd, const struct msghdr *__message,int __flags);#ifdef __USE_GNU
/* Send a VLEN messages as described by VMESSAGES to socket FD.Returns the number of datagrams successfully written or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern int sendmmsg (int __fd, struct mmsghdr *__vmessages,unsigned int __vlen, int __flags);
#endif/* Receive a message as described by MESSAGE from socket FD.Returns the number of bytes read or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags);#ifdef __USE_GNU
/* Receive up to VLEN messages as described by VMESSAGES from socket FD.Returns the number of messages received or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,unsigned int __vlen, int __flags,struct timespec *__tmo);
#endif/* Put the current value for socket FD's option OPTNAME at protocol level LEVELinto OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value'sactual length.  Returns 0 on success, -1 for errors.  */
extern int getsockopt (int __fd, int __level, int __optname,void *__restrict __optval,socklen_t *__restrict __optlen) __THROW;/* Set socket FD's option OPTNAME at protocol level LEVELto *OPTVAL (which is OPTLEN bytes long).Returns 0 on success, -1 for errors.  */
extern int setsockopt (int __fd, int __level, int __optname,const void *__optval, socklen_t __optlen) __THROW;/* Prepare to accept connections on socket FD.N connection requests will be queued before further requests are refused.Returns 0 on success, -1 for errors.  */
extern int listen (int __fd, int __n) __THROW;/* Await a connection on socket FD.When a connection arrives, open a new socket to communicate with it,set *ADDR (which is *ADDR_LEN bytes long) to the address of the connectingpeer and *ADDR_LEN to the address's actual length, and return thenew socket's descriptor, or -1 for errors.This function is a cancellation point and therefore not marked with__THROW.  */
extern int accept (int __fd, __SOCKADDR_ARG __addr,socklen_t *__restrict __addr_len);#ifdef __USE_GNU
/* Similar to 'accept' but takes an additional parameter to specify flags.This function is a cancellation point and therefore not marked with__THROW.  */
extern int accept4 (int __fd, __SOCKADDR_ARG __addr,socklen_t *__restrict __addr_len, int __flags);
#endif/* Shut down all or part of the connection open on socket FD.HOW determines what to shut down:SHUT_RD   = No more receptions;SHUT_WR   = No more transmissions;SHUT_RDWR = No more receptions or transmissions.Returns 0 on success, -1 for errors.  */
extern int shutdown (int __fd, int __how) __THROW;#ifdef __USE_XOPEN2K
/* Determine wheter socket is at a out-of-band mark.  */
extern int sockatmark (int __fd) __THROW;
#endif#ifdef __USE_MISC
/* FDTYPE is S_IFSOCK or another S_IF* macro defined in <sys/stat.h>;returns 1 if FD is open on an object of the indicated type, 0 if not,or -1 for errors (setting errno).  */
extern int isfdtype (int __fd, int __fdtype) __THROW;
#endif/* Define some macros helping to catch buffer overflows.  */
#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
# include <bits/socket2.h>
#endif__END_DECLS#endif /* sys/socket.h */

3.2 一些格式转换的API

/usr/include/netinet/in.h

主要的几个函数就是这个

extern uint32_t ntohl (uint32_t __netlong)  //将一个无符号长整形数从网络字节顺序转换为主机字节顺序, ntohl()返回一个以主机字节顺序表达的数
extern uint16_t ntohs (uint16_t __netshort) //将一个16位数由网络字节顺序转换为主机字节顺序。
extern uint32_t htonl (uint32_t __hostlong) //将主机数转换成无符号长整型的网络字节顺序。本函数将一个32位数从主机字节顺序转换成网络字节顺序
extern uint16_t htons (uint16_t __hostshort) //将整型变量从主机字节顺序转变成网络字节顺序,//就是整数在地址空间存储方式变为高位字节存放在内存的低地址处
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with the GNU C Library; if not, see<http://www.gnu.org/licenses/>.  */#ifndef _NETINET_IN_H
#define _NETINET_IN_H   1#include <features.h>
#include <bits/stdint-uintn.h>
#include <sys/socket.h>
#include <bits/types.h>__BEGIN_DECLS/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;};/* Get system-specific definitions.  */
#include <bits/in.h>/* Standard well-defined IP protocols.  */
enum{IPPROTO_IP = 0,        /* Dummy protocol for TCP.  */
#define IPPROTO_IP              IPPROTO_IPIPPROTO_ICMP = 1,      /* Internet Control Message Protocol.  */
#define IPPROTO_ICMP            IPPROTO_ICMPIPPROTO_IGMP = 2,      /* Internet Group Management Protocol. */
#define IPPROTO_IGMP            IPPROTO_IGMPIPPROTO_IPIP = 4,      /* IPIP tunnels (older KA9Q tunnels use 94).  */
#define IPPROTO_IPIP            IPPROTO_IPIPIPPROTO_TCP = 6,       /* Transmission Control Protocol.  */
#define IPPROTO_TCP             IPPROTO_TCPIPPROTO_EGP = 8,       /* Exterior Gateway Protocol.  */
#define IPPROTO_EGP             IPPROTO_EGPIPPROTO_PUP = 12,      /* PUP protocol.  */
#define IPPROTO_PUP             IPPROTO_PUPIPPROTO_UDP = 17,      /* User Datagram Protocol.  */
#define IPPROTO_UDP             IPPROTO_UDPIPPROTO_IDP = 22,      /* XNS IDP protocol.  */
#define IPPROTO_IDP             IPPROTO_IDPIPPROTO_TP = 29,       /* SO Transport Protocol Class 4.  */
#define IPPROTO_TP              IPPROTO_TPIPPROTO_DCCP = 33,     /* Datagram Congestion Control Protocol.  */
#define IPPROTO_DCCP            IPPROTO_DCCPIPPROTO_IPV6 = 41,     /* IPv6 header.  */
#define IPPROTO_IPV6            IPPROTO_IPV6IPPROTO_RSVP = 46,     /* Reservation Protocol.  */
#define IPPROTO_RSVP            IPPROTO_RSVPIPPROTO_GRE = 47,      /* General Routing Encapsulation.  */
#define IPPROTO_GRE             IPPROTO_GREIPPROTO_ESP = 50,      /* encapsulating security payload.  */
#define IPPROTO_ESP             IPPROTO_ESPIPPROTO_AH = 51,       /* authentication header.  */
#define IPPROTO_AH              IPPROTO_AHIPPROTO_MTP = 92,      /* Multicast Transport Protocol.  */
#define IPPROTO_MTP             IPPROTO_MTPIPPROTO_BEETPH = 94,   /* IP option pseudo header for BEET.  */
#define IPPROTO_BEETPH          IPPROTO_BEETPHIPPROTO_ENCAP = 98,    /* Encapsulation Header.  */
#define IPPROTO_ENCAP           IPPROTO_ENCAPIPPROTO_PIM = 103,     /* Protocol Independent Multicast.  */
#define IPPROTO_PIM             IPPROTO_PIMIPPROTO_COMP = 108,    /* Compression Header Protocol.  */
#define IPPROTO_COMP            IPPROTO_COMPIPPROTO_SCTP = 132,    /* Stream Control Transmission Protocol.  */
#define IPPROTO_SCTP            IPPROTO_SCTPIPPROTO_UDPLITE = 136, /* UDP-Lite protocol.  */
#define IPPROTO_UDPLITE         IPPROTO_UDPLITEIPPROTO_MPLS = 137,    /* MPLS in IP.  */
#define IPPROTO_MPLS            IPPROTO_MPLSIPPROTO_RAW = 255,     /* Raw IP packets.  */
#define IPPROTO_RAW             IPPROTO_RAWIPPROTO_MAX};/* If __USE_KERNEL_IPV6_DEFS is 1 then the user has included the kernelnetwork headers first and we should use those ABI-identical definitionsinstead of our own, otherwise 0.  */
#if !__USE_KERNEL_IPV6_DEFS
enum{IPPROTO_HOPOPTS = 0,   /* IPv6 Hop-by-Hop options.  */
#define IPPROTO_HOPOPTS         IPPROTO_HOPOPTSIPPROTO_ROUTING = 43,  /* IPv6 routing header.  */
#define IPPROTO_ROUTING         IPPROTO_ROUTINGIPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header.  */
#define IPPROTO_FRAGMENT        IPPROTO_FRAGMENTIPPROTO_ICMPV6 = 58,   /* ICMPv6.  */
#define IPPROTO_ICMPV6          IPPROTO_ICMPV6IPPROTO_NONE = 59,     /* IPv6 no next header.  */
#define IPPROTO_NONE            IPPROTO_NONEIPPROTO_DSTOPTS = 60,  /* IPv6 destination options.  */
#define IPPROTO_DSTOPTS         IPPROTO_DSTOPTSIPPROTO_MH = 135       /* IPv6 mobility header.  */
#define IPPROTO_MH              IPPROTO_MH};
#endif /* !__USE_KERNEL_IPV6_DEFS *//* Type to represent a port.  */
typedef uint16_t in_port_t;/* Standard well-known ports.  */
enum{IPPORT_ECHO = 7,            /* Echo service.  */IPPORT_DISCARD = 9,         /* Discard transmissions service.  */IPPORT_SYSTAT = 11,         /* System status service.  */IPPORT_DAYTIME = 13,        /* Time of day service.  */IPPORT_NETSTAT = 15,        /* Network status service.  */IPPORT_FTP = 21,            /* File Transfer Protocol.  */IPPORT_TELNET = 23,         /* Telnet protocol.  */IPPORT_SMTP = 25,           /* Simple Mail Transfer Protocol.  */IPPORT_TIMESERVER = 37,     /* Timeserver service.  */IPPORT_NAMESERVER = 42,     /* Domain Name Service.  */IPPORT_WHOIS = 43,          /* Internet Whois service.  */IPPORT_MTP = 57,IPPORT_TFTP = 69,           /* Trivial File Transfer Protocol.  */IPPORT_RJE = 77,IPPORT_FINGER = 79,         /* Finger service.  */IPPORT_TTYLINK = 87,IPPORT_SUPDUP = 95,         /* SUPDUP protocol.  */IPPORT_EXECSERVER = 512,    /* execd service.  */IPPORT_LOGINSERVER = 513,   /* rlogind service.  */IPPORT_CMDSERVER = 514,IPPORT_EFSSERVER = 520,/* UDP ports.  */IPPORT_BIFFUDP = 512,IPPORT_WHOSERVER = 513,IPPORT_ROUTESERVER = 520,/* Ports less than this value are reserved for privileged processes.  */IPPORT_RESERVED = 1024,/* Ports greater this value are reserved for (non-privileged) servers.  */IPPORT_USERRESERVED = 5000};/* Definitions of the bits in an Internet address integer.On subnets, host and network parts are found according tothe subnet mask, not these masks.  */#define IN_CLASSA(a)            ((((in_addr_t)(a)) & 0x80000000) == 0)
#define IN_CLASSA_NET           0xff000000
#define IN_CLASSA_NSHIFT        24
#define IN_CLASSA_HOST          (0xffffffff & ~IN_CLASSA_NET)
#define IN_CLASSA_MAX           128#define IN_CLASSB(a)            ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
#define IN_CLASSB_NET           0xffff0000
#define IN_CLASSB_NSHIFT        16
#define IN_CLASSB_HOST          (0xffffffff & ~IN_CLASSB_NET)
#define IN_CLASSB_MAX           65536#define IN_CLASSC(a)            ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
#define IN_CLASSC_NET           0xffffff00
#define IN_CLASSC_NSHIFT        8
#define IN_CLASSC_HOST          (0xffffffff & ~IN_CLASSC_NET)#define IN_CLASSD(a)            ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
#define IN_MULTICAST(a)         IN_CLASSD(a)#define IN_EXPERIMENTAL(a)      ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
#define IN_BADCLASS(a)          ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)/* Address to accept any incoming messages.  */
#define INADDR_ANY              ((in_addr_t) 0x00000000)
/* Address to send to all hosts.  */
#define INADDR_BROADCAST        ((in_addr_t) 0xffffffff)
/* Address indicating an error return.  */
#define INADDR_NONE             ((in_addr_t) 0xffffffff)/* Network number for local host loopback.  */
#define IN_LOOPBACKNET          127
/* Address to loopback in software to local host.  */
#ifndef INADDR_LOOPBACK
# define INADDR_LOOPBACK        ((in_addr_t) 0x7f000001) /* Inet 127.0.0.1.  */
#endif/* Defines for Multicast INADDR.  */
#define INADDR_UNSPEC_GROUP     ((in_addr_t) 0xe0000000) /* 224.0.0.0 */
#define INADDR_ALLHOSTS_GROUP   ((in_addr_t) 0xe0000001) /* 224.0.0.1 */
#define INADDR_ALLRTRS_GROUP    ((in_addr_t) 0xe0000002) /* 224.0.0.2 */
#define INADDR_MAX_LOCAL_GROUP  ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */#if !__USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr{union{uint8_t __u6_addr8[16];uint16_t __u6_addr16[8];uint32_t __u6_addr32[4];} __in6_u;
#define s6_addr                 __in6_u.__u6_addr8
#ifdef __USE_MISC
# define s6_addr16              __in6_u.__u6_addr16
# define s6_addr32              __in6_u.__u6_addr32
#endif};
#endif /* !__USE_KERNEL_IPV6_DEFS */extern const struct in6_addr in6addr_any;        /* :: */
extern const struct in6_addr in6addr_loopback;   /* ::1 */
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46/* Structure describing an Internet socket address.  */
struct sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port;                 /* Port number.  */struct in_addr sin_addr;            /* Internet address.  *//* Pad to size of `struct sockaddr'.  */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];};#if !__USE_KERNEL_IPV6_DEFS
/* Ditto, for IPv6.  */
struct sockaddr_in6{__SOCKADDR_COMMON (sin6_);in_port_t sin6_port;        /* Transport layer port # */uint32_t sin6_flowinfo;     /* IPv6 flow information */struct in6_addr sin6_addr;  /* IPv6 address */uint32_t sin6_scope_id;     /* IPv6 scope-id */};
#endif /* !__USE_KERNEL_IPV6_DEFS */#ifdef __USE_MISC
/* IPv4 multicast request.  */
struct ip_mreq{/* IP multicast address of group.  */struct in_addr imr_multiaddr;/* Local IP address of interface.  */struct in_addr imr_interface;};struct ip_mreq_source{/* IP multicast address of group.  */struct in_addr imr_multiaddr;/* IP address of interface.  */struct in_addr imr_interface;/* IP address of source.  */struct in_addr imr_sourceaddr;};
#endif#if !__USE_KERNEL_IPV6_DEFS
/* Likewise, for IPv6.  */
struct ipv6_mreq{/* IPv6 multicast address of group */struct in6_addr ipv6mr_multiaddr;/* local interface */unsigned int ipv6mr_interface;};
#endif /* !__USE_KERNEL_IPV6_DEFS */#ifdef __USE_MISC
/* Multicast group request.  */
struct group_req{/* Interface index.  */uint32_t gr_interface;/* Group address.  */struct sockaddr_storage gr_group;};struct group_source_req{/* Interface index.  */uint32_t gsr_interface;/* Group address.  */struct sockaddr_storage gsr_group;/* Source address.  */struct sockaddr_storage gsr_source;};/* Full-state filter operations.  */
struct ip_msfilter{/* IP multicast address of group.  */struct in_addr imsf_multiaddr;/* Local IP address of interface.  */struct in_addr imsf_interface;/* Filter mode.  */uint32_t imsf_fmode;/* Number of source addresses.  */uint32_t imsf_numsrc;/* Source addresses.  */struct in_addr imsf_slist[1];};#define IP_MSFILTER_SIZE(numsrc) (sizeof (struct ip_msfilter) \- sizeof (struct in_addr)                   \+ (numsrc) * sizeof (struct in_addr))struct group_filter{/* Interface index.  */uint32_t gf_interface;/* Group address.  */struct sockaddr_storage gf_group;/* Filter mode.  */uint32_t gf_fmode;/* Number of source addresses.  */uint32_t gf_numsrc;/* Source addresses.  */struct sockaddr_storage gf_slist[1];
};#define GROUP_FILTER_SIZE(numsrc) (sizeof (struct group_filter) \- sizeof (struct sockaddr_storage)         \+ ((numsrc)                                \* sizeof (struct sockaddr_storage)))
#endif/* Functions to convert between host and network byte order.Please note that these functions normally take `unsigned long int' or`unsigned short int' values as arguments and also return them.  Butthis was a short-sighted decision since on different systems the typesmay have different representations but the values are always the same.  */extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));
extern uint16_t ntohs (uint16_t __netshort)__THROW __attribute__ ((__const__));
extern uint32_t htonl (uint32_t __hostlong)__THROW __attribute__ ((__const__));
extern uint16_t htons (uint16_t __hostshort)__THROW __attribute__ ((__const__));#include <endian.h>/* Get machine dependent optimized versions of byte swapping functions.  */
#include <bits/byteswap.h>
#include <bits/uintn-identity.h>#ifdef __OPTIMIZE__
/* We can optimize calls to the conversion functions.  Either nothing hasto be done or we are using directly the byte-swapping functions whichoften can be inlined.  */
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,so these functions are all just identity.  */
# define ntohl(x)       __uint32_identity (x)
# define ntohs(x)       __uint16_identity (x)
# define htonl(x)       __uint32_identity (x)
# define htons(x)       __uint16_identity (x)
# else
#  if __BYTE_ORDER == __LITTLE_ENDIAN
#   define ntohl(x)     __bswap_32 (x)
#   define ntohs(x)     __bswap_16 (x)
#   define htonl(x)     __bswap_32 (x)
#   define htons(x)     __bswap_16 (x)
#  endif
# endif
#endif#ifdef __GNUC__
# define IN6_IS_ADDR_UNSPECIFIED(a) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \__a->__in6_u.__u6_addr32[0] == 0                                        \&& __a->__in6_u.__u6_addr32[1] == 0                                     \&& __a->__in6_u.__u6_addr32[2] == 0                                     \&& __a->__in6_u.__u6_addr32[3] == 0; }))# define IN6_IS_ADDR_LOOPBACK(a) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \__a->__in6_u.__u6_addr32[0] == 0                                        \&& __a->__in6_u.__u6_addr32[1] == 0                                     \&& __a->__in6_u.__u6_addr32[2] == 0                                     \&& __a->__in6_u.__u6_addr32[3] == htonl (1); }))# define IN6_IS_ADDR_LINKLOCAL(a) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \(__a->__in6_u.__u6_addr32[0] & htonl (0xffc00000)) == htonl (0xfe800000); }))# define IN6_IS_ADDR_SITELOCAL(a) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \(__a->__in6_u.__u6_addr32[0] & htonl (0xffc00000)) == htonl (0xfec00000); }))# define IN6_IS_ADDR_V4MAPPED(a) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \__a->__in6_u.__u6_addr32[0] == 0                                        \&& __a->__in6_u.__u6_addr32[1] == 0                                     \&& __a->__in6_u.__u6_addr32[2] == htonl (0xffff); }))# define IN6_IS_ADDR_V4COMPAT(a) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \__a->__in6_u.__u6_addr32[0] == 0                                        \&& __a->__in6_u.__u6_addr32[1] == 0                                     \&& __a->__in6_u.__u6_addr32[2] == 0                                     \&& ntohl (__a->__in6_u.__u6_addr32[3]) > 1; }))# define IN6_ARE_ADDR_EQUAL(a,b) \(__extension__                                                              \({ const struct in6_addr *__a = (const struct in6_addr *) (a);             \const struct in6_addr *__b = (const struct in6_addr *) (b);             \__a->__in6_u.__u6_addr32[0] == __b->__in6_u.__u6_addr32[0]              \&& __a->__in6_u.__u6_addr32[1] == __b->__in6_u.__u6_addr32[1]           \&& __a->__in6_u.__u6_addr32[2] == __b->__in6_u.__u6_addr32[2]           \&& __a->__in6_u.__u6_addr32[3] == __b->__in6_u.__u6_addr32[3]; }))
#else
# define IN6_IS_ADDR_UNSPECIFIED(a) \(((const uint32_t *) (a))[0] == 0                                     \&& ((const uint32_t *) (a))[1] == 0                                  \&& ((const uint32_t *) (a))[2] == 0                                  \&& ((const uint32_t *) (a))[3] == 0)# define IN6_IS_ADDR_LOOPBACK(a) \(((const uint32_t *) (a))[0] == 0                                     \&& ((const uint32_t *) (a))[1] == 0                                  \&& ((const uint32_t *) (a))[2] == 0                                  \&& ((const uint32_t *) (a))[3] == htonl (1))# define IN6_IS_ADDR_LINKLOCAL(a) \((((const uint32_t *) (a))[0] & htonl (0xffc00000))                   \== htonl (0xfe800000))# define IN6_IS_ADDR_SITELOCAL(a) \((((const uint32_t *) (a))[0] & htonl (0xffc00000))                   \== htonl (0xfec00000))# define IN6_IS_ADDR_V4MAPPED(a) \((((const uint32_t *) (a))[0] == 0)                                   \&& (((const uint32_t *) (a))[1] == 0)                                \&& (((const uint32_t *) (a))[2] == htonl (0xffff)))# define IN6_IS_ADDR_V4COMPAT(a) \((((const uint32_t *) (a))[0] == 0)                                   \&& (((const uint32_t *) (a))[1] == 0)                                \&& (((const uint32_t *) (a))[2] == 0)                                \&& (ntohl (((const uint32_t *) (a))[3]) > 1))# define IN6_ARE_ADDR_EQUAL(a,b) \((((const uint32_t *) (a))[0] == ((const uint32_t *) (b))[0])         \&& (((const uint32_t *) (a))[1] == ((const uint32_t *) (b))[1])      \&& (((const uint32_t *) (a))[2] == ((const uint32_t *) (b))[2])      \&& (((const uint32_t *) (a))[3] == ((const uint32_t *) (b))[3]))
#endif#define IN6_IS_ADDR_MULTICAST(a) (((const uint8_t *) (a))[0] == 0xff)#ifdef __USE_MISC
/* Bind socket to a privileged IP port.  */
extern int bindresvport (int __sockfd, struct sockaddr_in *__sock_in) __THROW;/* The IPv6 version of this function.  */
extern int bindresvport6 (int __sockfd, struct sockaddr_in6 *__sock_in)__THROW;
#endif#define IN6_IS_ADDR_MC_NODELOCAL(a) \(IN6_IS_ADDR_MULTICAST(a)                                             \&& ((((const uint8_t *) (a))[1] & 0xf) == 0x1))#define IN6_IS_ADDR_MC_LINKLOCAL(a) \(IN6_IS_ADDR_MULTICAST(a)                                             \&& ((((const uint8_t *) (a))[1] & 0xf) == 0x2))#define IN6_IS_ADDR_MC_SITELOCAL(a) \(IN6_IS_ADDR_MULTICAST(a)                                             \&& ((((const uint8_t *) (a))[1] & 0xf) == 0x5))#define IN6_IS_ADDR_MC_ORGLOCAL(a) \(IN6_IS_ADDR_MULTICAST(a)                                             \&& ((((const uint8_t *) (a))[1] & 0xf) == 0x8))#define IN6_IS_ADDR_MC_GLOBAL(a) \(IN6_IS_ADDR_MULTICAST(a)                                             \&& ((((const uint8_t *) (a))[1] & 0xf) == 0xe))#ifdef __USE_GNU
struct cmsghdr;                 /* Forward declaration.  */#if !__USE_KERNEL_IPV6_DEFS
/* IPv6 packet information.  */
struct in6_pktinfo{struct in6_addr ipi6_addr;  /* src/dst IPv6 address */unsigned int ipi6_ifindex;  /* send/recv interface index */};/* IPv6 MTU information.  */
struct ip6_mtuinfo{struct sockaddr_in6 ip6m_addr; /* dst address including zone ID */uint32_t ip6m_mtu;             /* path MTU in host byte order */};
#endif /* !__USE_KERNEL_IPV6_DEFS *//* Obsolete hop-by-hop and Destination Options Processing (RFC 2292).  */
extern int inet6_option_space (int __nbytes)__THROW __attribute_deprecated__;
extern int inet6_option_init (void *__bp, struct cmsghdr **__cmsgp,int __type) __THROW __attribute_deprecated__;
extern int inet6_option_append (struct cmsghdr *__cmsg,const uint8_t *__typep, int __multx,int __plusy) __THROW __attribute_deprecated__;
extern uint8_t *inet6_option_alloc (struct cmsghdr *__cmsg, int __datalen,int __multx, int __plusy)__THROW __attribute_deprecated__;
extern int inet6_option_next (const struct cmsghdr *__cmsg,uint8_t **__tptrp)__THROW __attribute_deprecated__;
extern int inet6_option_find (const struct cmsghdr *__cmsg,uint8_t **__tptrp, int __type)__THROW __attribute_deprecated__;/* Hop-by-Hop and Destination Options Processing (RFC 3542).  */
extern int inet6_opt_init (void *__extbuf, socklen_t __extlen) __THROW;
extern int inet6_opt_append (void *__extbuf, socklen_t __extlen, int __offset,uint8_t __type, socklen_t __len, uint8_t __align,void **__databufp) __THROW;
extern int inet6_opt_finish (void *__extbuf, socklen_t __extlen, int __offset)__THROW;
extern int inet6_opt_set_val (void *__databuf, int __offset, void *__val,socklen_t __vallen) __THROW;
extern int inet6_opt_next (void *__extbuf, socklen_t __extlen, int __offset,uint8_t *__typep, socklen_t *__lenp,void **__databufp) __THROW;
extern int inet6_opt_find (void *__extbuf, socklen_t __extlen, int __offset,uint8_t __type, socklen_t *__lenp,void **__databufp) __THROW;
extern int inet6_opt_get_val (void *__databuf, int __offset, void *__val,socklen_t __vallen) __THROW;/* Routing Header Option (RFC 3542).  */
extern socklen_t inet6_rth_space (int __type, int __segments) __THROW;
extern void *inet6_rth_init (void *__bp, socklen_t __bp_len, int __type,int __segments) __THROW;
extern int inet6_rth_add (void *__bp, const struct in6_addr *__addr) __THROW;
extern int inet6_rth_reverse (const void *__in, void *__out) __THROW;
extern int inet6_rth_segments (const void *__bp) __THROW;
extern struct in6_addr *inet6_rth_getaddr (const void *__bp, int __index)__THROW;/* Multicast source filter support.  *//* Get IPv4 source filter.  */
extern int getipv4sourcefilter (int __s, struct in_addr __interface_addr,struct in_addr __group, uint32_t *__fmode,uint32_t *__numsrc, struct in_addr *__slist)__THROW;/* Set IPv4 source filter.  */
extern int setipv4sourcefilter (int __s, struct in_addr __interface_addr,struct in_addr __group, uint32_t __fmode,uint32_t __numsrc,const struct in_addr *__slist)__THROW;/* Get source filter.  */
extern int getsourcefilter (int __s, uint32_t __interface_addr,const struct sockaddr *__group,socklen_t __grouplen, uint32_t *__fmode,uint32_t *__numsrc,struct sockaddr_storage *__slist) __THROW;/* Set source filter.  */
extern int setsourcefilter (int __s, uint32_t __interface_addr,const struct sockaddr *__group,socklen_t __grouplen, uint32_t __fmode,uint32_t __numsrc,const struct sockaddr_storage *__slist) __THROW;
#endif  /* use GNU */__END_DECLS#endif  /* netinet/in.h */

3.3 一些基本宏定义以及一些结构体的定义

/usr/include/netdb.h

  /* Copyright (C) 1996-2018 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with the GNU C Library; if not, see<http://www.gnu.org/licenses/>.  *//* All data returned by the network data base library are supplied inhost order and returned in network order (suitable for use insystem calls).  */#ifndef _NETDB_H
#define _NETDB_H        1#include <features.h>#include <netinet/in.h>
#include <bits/stdint-uintn.h>
#ifdef __USE_MISC
/* This is necessary to make this include file properly replace theSun version.  */
# include <rpc/netdb.h>
#endif#ifdef __USE_GNU
# include <bits/types/sigevent_t.h>
# include <bits/types/struct_timespec.h>
#endif#include <bits/netdb.h>/* Absolute file name for network data base files.  */
#define _PATH_HEQUIV            "/etc/hosts.equiv"
#define _PATH_HOSTS             "/etc/hosts"
#define _PATH_NETWORKS          "/etc/networks"
#define _PATH_NSSWITCH_CONF     "/etc/nsswitch.conf"
#define _PATH_PROTOCOLS         "/etc/protocols"
#define _PATH_SERVICES          "/etc/services"__BEGIN_DECLS#if defined __USE_MISC || !defined __USE_XOPEN2K8
/* Error status for non-reentrant lookup functions.We use a macro to access always the thread-specific `h_errno' variable.  */
# define h_errno (*__h_errno_location ())/* Function to get address of global `h_errno' variable.  */
extern int *__h_errno_location (void) __THROW __attribute__ ((__const__));/* Possible values left in `h_errno'.  */
# define HOST_NOT_FOUND 1       /* Authoritative Answer Host not found.  */
# define TRY_AGAIN      2       /* Non-Authoritative Host not found,or SERVERFAIL.  */
# define NO_RECOVERY    3       /* Non recoverable errors, FORMERR, REFUSED,NOTIMP.  */
# define NO_DATA        4       /* Valid name, no data record of requestedtype.  */
#endif
#ifdef __USE_MISC
# define NETDB_INTERNAL -1      /* See errno.  */
# define NETDB_SUCCESS  0       /* No problem.  */
# define NO_ADDRESS     NO_DATA /* No address, look for MX record.  */
#endif#if defined __USE_XOPEN2K || defined __USE_XOPEN_EXTENDED
/* Highest reserved Internet port number.  */
# define IPPORT_RESERVED        1024
#endif#ifdef __USE_GNU
/* Scope delimiter for getaddrinfo(), getnameinfo().  */
# define SCOPE_DELIMITER        '%'
#endif#ifdef __USE_MISC
/* Print error indicated by `h_errno' variable on standard error.  STRif non-null is printed before the error string.  */
extern void herror (const char *__str) __THROW;/* Return string associated with error ERR_NUM.  */
extern const char *hstrerror (int __err_num) __THROW;
#endif/* Description of data base entry for a single host.  */
struct hostent
{char *h_name;                 /* Official name of host.  */char **h_aliases;             /* Alias list.  */int h_addrtype;               /* Host address type.  */int h_length;                 /* Length of address.  */char **h_addr_list;           /* List of addresses from name server.  */
#ifdef __USE_MISC
# define        h_addr  h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};/* Open host data base files and mark them as staying open even aftera later search if STAY_OPEN is non-zero.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void sethostent (int __stay_open);/* Close host data base files and clear `stay open' flag.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void endhostent (void);/* Get next entry from host data base file.  Open data base ifnecessary.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct hostent *gethostent (void);/* Return entry from host data base which address match ADDR withlength LEN and type TYPE.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct hostent *gethostbyaddr (const void *__addr, __socklen_t __len,int __type);/* Return entry from host data base for host with NAME.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct hostent *gethostbyname (const char *__name);#ifdef __USE_MISC
/* Return entry from host data base for host with NAME.  AF must beset to the address type which is `AF_INET' for IPv4 or `AF_INET6'for IPv6.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern struct hostent *gethostbyname2 (const char *__name, int __af);/* Reentrant versions of the functions above.  The additionalarguments specify a buffer of BUFLEN starting at BUF.  The lastargument is a pointer to a variable which gets the value whichwould be stored in the global variable `herrno' by thenon-reentrant functions.These functions are not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation they are cancellation points andtherefore not marked with __THROW.  */
extern int gethostent_r (struct hostent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct hostent **__restrict __result,int *__restrict __h_errnop);extern int gethostbyaddr_r (const void *__restrict __addr, __socklen_t __len,int __type,struct hostent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct hostent **__restrict __result,int *__restrict __h_errnop);extern int gethostbyname_r (const char *__restrict __name,struct hostent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct hostent **__restrict __result,int *__restrict __h_errnop);extern int gethostbyname2_r (const char *__restrict __name, int __af,struct hostent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct hostent **__restrict __result,int *__restrict __h_errnop);
#endif  /* misc *//* Open network data base files and mark them as staying open evenafter a later search if STAY_OPEN is non-zero.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void setnetent (int __stay_open);/* Close network data base files and clear `stay open' flag.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void endnetent (void);/* Get next entry from network data base file.  Open data base ifnecessary.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct netent *getnetent (void);/* Return entry from network data base which address match NET andtype TYPE.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct netent *getnetbyaddr (uint32_t __net, int __type);/* Return entry from network data base for network with NAME.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct netent *getnetbyname (const char *__name);#ifdef  __USE_MISC
/* Reentrant versions of the functions above.  The additionalarguments specify a buffer of BUFLEN starting at BUF.  The lastargument is a pointer to a variable which gets the value whichwould be stored in the global variable `herrno' by thenon-reentrant functions.These functions are not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation they are cancellation points andtherefore not marked with __THROW.  */
extern int getnetent_r (struct netent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct netent **__restrict __result,int *__restrict __h_errnop);extern int getnetbyaddr_r (uint32_t __net, int __type,struct netent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct netent **__restrict __result,int *__restrict __h_errnop);extern int getnetbyname_r (const char *__restrict __name,struct netent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct netent **__restrict __result,int *__restrict __h_errnop);
#endif  /* misc *//* Description of data base entry for a single service.  */
struct servent
{char *s_name;                 /* Official service name.  */char **s_aliases;             /* Alias list.  */int s_port;                   /* Port number.  */char *s_proto;                /* Protocol to use.  */
};/* Open service data base files and mark them as staying open evenafter a later search if STAY_OPEN is non-zero.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void setservent (int __stay_open);/* Close service data base files and clear `stay open' flag.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void endservent (void);/* Get next entry from service data base file.  Open data base ifnecessary.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct servent *getservent (void);/* Return entry from network data base for network with NAME andprotocol PROTO.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct servent *getservbyname (const char *__name, const char *__proto);/* Return entry from service data base which matches port PORT andprotocol PROTO.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct servent *getservbyport (int __port, const char *__proto);#ifdef  __USE_MISC
/* Reentrant versions of the functions above.  The additionalarguments specify a buffer of BUFLEN starting at BUF.These functions are not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation they are cancellation points andtherefore not marked with __THROW.  */
extern int getservent_r (struct servent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct servent **__restrict __result);extern int getservbyname_r (const char *__restrict __name,const char *__restrict __proto,struct servent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct servent **__restrict __result);extern int getservbyport_r (int __port, const char *__restrict __proto,struct servent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct servent **__restrict __result);
#endif  /* misc *//* Description of data base entry for a single service.  */
struct protoent
{char *p_name;                 /* Official protocol name.  */char **p_aliases;             /* Alias list.  */int p_proto;                  /* Protocol number.  */
};/* Open protocol data base files and mark them as staying open evenafter a later search if STAY_OPEN is non-zero.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void setprotoent (int __stay_open);/* Close protocol data base files and clear `stay open' flag.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern void endprotoent (void);/* Get next entry from protocol data base file.  Open data base ifnecessary.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct protoent *getprotoent (void);/* Return entry from protocol data base for network with NAME.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct protoent *getprotobyname (const char *__name);/* Return entry from protocol data base which number is PROTO.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern struct protoent *getprotobynumber (int __proto);#ifdef  __USE_MISC
/* Reentrant versions of the functions above.  The additionalarguments specify a buffer of BUFLEN starting at BUF.These functions are not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation they are cancellation points andtherefore not marked with __THROW.  */
extern int getprotoent_r (struct protoent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct protoent **__restrict __result);extern int getprotobyname_r (const char *__restrict __name,struct protoent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct protoent **__restrict __result);extern int getprotobynumber_r (int __proto,struct protoent *__restrict __result_buf,char *__restrict __buf, size_t __buflen,struct protoent **__restrict __result);/* Establish network group NETGROUP for enumeration.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int setnetgrent (const char *__netgroup);/* Free all space allocated by previous `setnetgrent' call.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern void endnetgrent (void);/* Get next member of netgroup established by last `setnetgrent' calland return pointers to elements in HOSTP, USERP, and DOMAINP.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int getnetgrent (char **__restrict __hostp,char **__restrict __userp,char **__restrict __domainp);/* Test whether NETGROUP contains the triple (HOST,USER,DOMAIN).This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int innetgr (const char *__netgroup, const char *__host,const char *__user, const char *__domain);/* Reentrant version of `getnetgrent' where result is placed in BUFFER.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int getnetgrent_r (char **__restrict __hostp,char **__restrict __userp,char **__restrict __domainp,char *__restrict __buffer, size_t __buflen);
#endif  /* misc */#ifdef __USE_MISC
/* Call `rshd' at port RPORT on remote machine *AHOST to execute CMD.The local user is LOCUSER, on the remote machine the command isexecuted as REMUSER.  In *FD2P the descriptor to the socket for theconnection is returned.  The caller must have the right to use areserved port.  When the function returns *AHOST contains theofficial host name.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int rcmd (char **__restrict __ahost, unsigned short int __rport,const char *__restrict __locuser,const char *__restrict __remuser,const char *__restrict __cmd, int *__restrict __fd2p);/* This is the equivalent function where the protocol can be selectedand which therefore can be used for IPv6.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int rcmd_af (char **__restrict __ahost, unsigned short int __rport,const char *__restrict __locuser,const char *__restrict __remuser,const char *__restrict __cmd, int *__restrict __fd2p,sa_family_t __af);/* Call `rexecd' at port RPORT on remote machine *AHOST to executeCMD.  The process runs at the remote machine using the ID of userNAME whose cleartext password is PASSWD.  In *FD2P the descriptorto the socket for the connection is returned.  When the functionreturns *AHOST contains the official host name.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int rexec (char **__restrict __ahost, int __rport,const char *__restrict __name,const char *__restrict __pass,const char *__restrict __cmd, int *__restrict __fd2p);/* This is the equivalent function where the protocol can be selectedand which therefore can be used for IPv6.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int rexec_af (char **__restrict __ahost, int __rport,const char *__restrict __name,const char *__restrict __pass,const char *__restrict __cmd, int *__restrict __fd2p,sa_family_t __af);/* Check whether user REMUSER on system RHOST is allowed to login as LOCUSER.If SUSER is not zero the user tries to become superuser.  Return 0 ifit is possible.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int ruserok (const char *__rhost, int __suser,const char *__remuser, const char *__locuser);/* This is the equivalent function where the protocol can be selectedand which therefore can be used for IPv6.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int ruserok_af (const char *__rhost, int __suser,const char *__remuser, const char *__locuser,sa_family_t __af);/* Check whether user REMUSER on system indicated by IPv4 addressRADDR is allowed to login as LOCUSER.  Non-IPv4 (e.g., IPv6) arenot supported.  If SUSER is not zero the user tries to becomesuperuser.  Return 0 if it is possible.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int iruserok (uint32_t __raddr, int __suser,const char *__remuser, const char *__locuser);/* This is the equivalent function where the pfamiliy if the addresspointed to by RADDR is determined by the value of AF.  It thereforecan be used for IPv6This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int iruserok_af (const void *__raddr, int __suser,const char *__remuser, const char *__locuser,sa_family_t __af);/* Try to allocate reserved port, returning a descriptor for a socket openedat this port or -1 if unsuccessful.  The search for an available portwill start at ALPORT and continues with lower numbers.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int rresvport (int *__alport);/* This is the equivalent function where the protocol can be selectedand which therefore can be used for IPv6.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int rresvport_af (int *__alport, sa_family_t __af);
#endif/* Extension from POSIX.1:2001.  */
#ifdef __USE_XOPEN2K
/* Structure to contain information about address of a service provider.  */
struct addrinfo
{int ai_flags;                 /* Input flags.  */int ai_family;                /* Protocol family for socket.  */int ai_socktype;              /* Socket type.  */int ai_protocol;              /* Protocol for socket.  */socklen_t ai_addrlen;         /* Length of socket address.  */struct sockaddr *ai_addr;     /* Socket address for socket.  */char *ai_canonname;           /* Canonical name for service location.  */struct addrinfo *ai_next;     /* Pointer to next in list.  */
};# ifdef __USE_GNU
/* Structure used as control block for asynchronous lookup.  */
struct gaicb
{const char *ar_name;          /* Name to look up.  */const char *ar_service;       /* Service name.  */const struct addrinfo *ar_request; /* Additional request specification.  */struct addrinfo *ar_result;   /* Pointer to result.  *//* The following are internal elements.  */int __return;int __glibc_reserved[5];
};/* Lookup mode.  */
#  define GAI_WAIT      0
#  define GAI_NOWAIT    1
# endif/* Possible values for `ai_flags' field in `addrinfo' structure.  */
# define AI_PASSIVE     0x0001  /* Socket address is intended for `bind'.  */
# define AI_CANONNAME   0x0002  /* Request for canonical name.  */
# define AI_NUMERICHOST 0x0004  /* Don't use name resolution.  */
# define AI_V4MAPPED    0x0008  /* IPv4 mapped addresses are acceptable.  */
# define AI_ALL         0x0010  /* Return IPv4 mapped and IPv6 addresses.  */
# define AI_ADDRCONFIG  0x0020  /* Use configuration of this host to choosereturned address type..  */
# ifdef __USE_GNU
#  define AI_IDN        0x0040  /* IDN encode input (assuming it is encodedin the current locale's character set)before looking it up. */
#  define AI_CANONIDN   0x0080  /* Translate canonical name from IDN format. */
#  define AI_IDN_ALLOW_UNASSIGNED 0x0100 /* Don't reject unassigned Unicodecode points.  */
#  define AI_IDN_USE_STD3_ASCII_RULES 0x0200 /* Validate strings according toSTD3 rules.  */
# endif
# define AI_NUMERICSERV 0x0400  /* Don't use name resolution.  *//* Error values for `getaddrinfo' function.  */
# define EAI_BADFLAGS     -1    /* Invalid value for `ai_flags' field.  */
# define EAI_NONAME       -2    /* NAME or SERVICE is unknown.  */
# define EAI_AGAIN        -3    /* Temporary failure in name resolution.  */
# define EAI_FAIL         -4    /* Non-recoverable failure in name res.  */
# define EAI_FAMILY       -6    /* `ai_family' not supported.  */
# define EAI_SOCKTYPE     -7    /* `ai_socktype' not supported.  */
# define EAI_SERVICE      -8    /* SERVICE not supported for `ai_socktype'.  */
# define EAI_MEMORY       -10   /* Memory allocation failure.  */
# define EAI_SYSTEM       -11   /* System error returned in `errno'.  */
# define EAI_OVERFLOW     -12   /* Argument buffer overflow.  */
# ifdef __USE_GNU
#  define EAI_NODATA      -5    /* No address associated with NAME.  */
#  define EAI_ADDRFAMILY  -9    /* Address family for NAME not supported.  */
#  define EAI_INPROGRESS  -100  /* Processing request in progress.  */
#  define EAI_CANCELED    -101  /* Request canceled.  */
#  define EAI_NOTCANCELED -102  /* Request not canceled.  */
#  define EAI_ALLDONE     -103  /* All requests done.  */
#  define EAI_INTR        -104  /* Interrupted by a signal.  */
#  define EAI_IDN_ENCODE  -105  /* IDN encoding failed.  */
# endif# ifdef __USE_MISC
#  define NI_MAXHOST      1025
#  define NI_MAXSERV      32
# endif# define NI_NUMERICHOST 1       /* Don't try to look up hostname.  */
# define NI_NUMERICSERV 2       /* Don't convert port number to name.  */
# define NI_NOFQDN      4       /* Only return nodename portion.  */
# define NI_NAMEREQD    8       /* Don't return numeric addresses.  */
# define NI_DGRAM       16      /* Look up UDP service rather than TCP.  */
# ifdef __USE_GNU
#  define NI_IDN        32      /* Convert name from IDN format.  */
#  define NI_IDN_ALLOW_UNASSIGNED 64 /* Don't reject unassigned Unicodecode points.  */
#  define NI_IDN_USE_STD3_ASCII_RULES 128 /* Validate strings according toSTD3 rules.  */
# endif/* Translate name of a service location and/or a service name to set ofsocket addresses.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern int getaddrinfo (const char *__restrict __name,const char *__restrict __service,const struct addrinfo *__restrict __req,struct addrinfo **__restrict __pai);/* Free `addrinfo' structure AI including associated storage.  */
extern void freeaddrinfo (struct addrinfo *__ai) __THROW;/* Convert error return from getaddrinfo() to a string.  */
extern const char *gai_strerror (int __ecode) __THROW;/* Translate a socket address to a location and service name.This function is a possible cancellation point and therefore notmarked with __THROW.  */
extern int getnameinfo (const struct sockaddr *__restrict __sa,socklen_t __salen, char *__restrict __host,socklen_t __hostlen, char *__restrict __serv,socklen_t __servlen, int __flags);
#endif  /* POSIX */#ifdef __USE_GNU
/* Enqueue ENT requests from the LIST.  If MODE is GAI_WAIT wait until allrequests are handled.  If WAIT is GAI_NOWAIT return immediately afterqueueing the requests and signal completion according to SIG.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr],int __ent, struct sigevent *__restrict __sig);/* Suspend execution of the thread until at least one of the ENT requestsin LIST is handled.  If TIMEOUT is not a null pointer it specifies thelongest time the function keeps waiting before returning with an error.This function is not part of POSIX and therefore no officialcancellation point.  But due to similarity with an POSIX interfaceor due to the implementation it is a cancellation point andtherefore not marked with __THROW.  */
extern int gai_suspend (const struct gaicb *const __list[], int __ent,const struct timespec *__timeout);/* Get the error status of the request REQ.  */
extern int gai_error (struct gaicb *__req) __THROW;/* Cancel the requests associated with GAICBP.  */
extern int gai_cancel (struct gaicb *__gaicbp) __THROW;
#endif  /* GNU */__END_DECLS#endif  /* netdb.h */

嵌入式linux学习笔记--TCP通讯整理相关推荐

  1. 迅为嵌入式Linux学习笔记4——进程

    迅为嵌入式Linux学习笔记4--进程 进程指的是正在运行的程序,是操作系统分配资源的最小单位. 进程ID 每个进程都有唯一的标识符,这个标识符就是进程ID,简称pid 进程间通信的方法 管道通信:分 ...

  2. 迅为嵌入式Linux学习笔记5——进程间通信

    迅为嵌入式Linux学习笔记5--进程间通信 管道通信 无名管道 无名管道只能实现有亲缘关系的进程之间的通信,比如父子进程. pipe函数: #include <unistd.h> int ...

  3. 嵌入式Linux学习笔记—fastboot烧写Android

    本系列为本人在自学过程中的学习笔记,如有错误欢迎大家指正. 学习资料为讯为ITOP4412开发板. fastboot烧写Android 1.主要工具 OTG 接口烧写方式也叫 fastboot 烧写方 ...

  4. Linux 学习笔记(自己整理仅供自己复习)

    前言 LINUX操作系统是一种免费使用和自由传播的类UNIX操作系统.其内核由林纳斯·托瓦兹于1991年10月5日首次发布,是一个基于POSIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运 ...

  5. 嵌入式linux学习笔记(一)

    最近开始学习linux驱动编写,目前直接使用jz2440已移植好的系统配合视频开始学习驱动编写,但是总是出现这样那样的问题.于是决定重头开始,先自己移植内核,在开始驱动学习. 今天参照<嵌入式l ...

  6. 嵌入式Linux学习笔记(1-1)——linux系统搭建

    版权声明:本文为博主原创文章,未经博主允许不得转载. 学习嵌入式linux已经有2年时间,虽然时间不长,但一路走来遇到很多问题,绕了很多弯路.写这篇文章的目的是分享我的经验,以供初学者参考,希望能够帮 ...

  7. 嵌入式linux编程,嵌入式Linux学习笔记 - 嵌入式Linux基础知识和开发环境的构建_Linux编程_Linux公社-Linux系统门户网站...

    注:所有内容基于友善之臂Mini2440开发板 一.嵌入式Linux开发环境的构建 嵌入式开发一般分为三个步骤: 1.编译bootloader,烧到开发板 2.编译嵌入式Linux内核,烧到开发板 3 ...

  8. linux内核编译选项ccl,嵌入式Linux学习笔记(一)

    注:所有内容基于友善之臂Mini2440开发板 一.嵌入式Linux开发环境的构建 嵌入式开发一般分为三个步骤: 1.编译bootloader,烧到开发板 2.编译嵌入式Linux内核,烧到开发板 3 ...

  9. 嵌入式Linux学习笔记(1-4)——下载bootoader

    俗话说万事开头难(然后中间难结尾难),拿到一款开发板之后,由于缺少教程或者教程不够详细等多种原因导致菜鸟一脸茫然无从下手,信心受挫,此时若有一个大牛在手把手指导哪该多好,但是大牛总是很忙--所以关键还 ...

最新文章

  1. 关于网页显示乱码问题的一些个人见解(PHP、JSP...)
  2. 99% 的新移动恶意程序是针对 Android
  3. 1月12日,HTML学习笔记2
  4. devices-list
  5. Unity3D Editor 扩展
  6. WKWebView概述
  7. WPF圆角按钮与触发颜色变化
  8. 四、内存空间的编辑和ASSIC码
  9. jenkinsapi操作Jenkins,提示:No valid crumb was included in the request
  10. SQL事务处理实验报告
  11. 训练赛第三场A题 zoj 559
  12. C语言rf,C89:关键字 - osc_fdjrfnux的个人空间 - OSCHINA - 中文开源技术交流社区
  13. windows 10 Office 2016 安装
  14. python绘制三角函数图像_用python画三角函数
  15. 持久层框架:Mybatis快速入门
  16. linux 更改时间时区,Linux下修改系统时区
  17. python大数加法、需要ut_对于密钥大小,Python加密数据太长
  18. 一、系统间的通信技术
  19. 如何制作WAV Audio DVD、AC3 Audio DVD、DTS Audio DVD封面音乐碟片?
  20. red hat enterprise linux yum,Red Hat Enterprise Linux7.x(RHEL7.x)更换CentOS YUM源

热门文章

  1. 17.7.19-聊天APP-登录界面
  2. 黑客是如何进行IP欺骗的
  3. 自制CPU(三)流水线
  4. bootstrap学习使用
  5. 反素数(反转拼写的素数)
  6. 企业级LNMP环境搭建
  7. C++项目--汇总(无工作经验或者不到两年工作经验者)
  8. 数学建模中的插值问题
  9. (一)Google Earth Engine概述
  10. iOS开发 Tips 保存视频文件到相册