现在的位置: 首页 > 综合 > 正文

glibc之socket网络编程

2013年08月19日 ⁄ 综合 ⁄ 共 16138字 ⁄ 字号 评论关闭

 //////////////////////////////////////////////////////////////////////////////////
 ///include/bits/sockaddr.h
  1 /* Definition of `struct sockaddr_*' common members.  Generic/4.2 BSD version*/
 19
 20 /*
 21  * Never include this file directly; use <sys/socket.h> instead.
 22  */
 23
 24 #ifndef _BITS_SOCKADDR_H
 25 #define _BITS_SOCKADDR_H    1
 26
 27
 28 /* POSIX.1g specifies this type name for the `sa_family' member.  */
 29 typedef unsigned short int sa_family_t;
 30
 31 /* This macro is used to declare the initial common members
 32    of the data types used for socket addresses, `struct sockaddr',
 33    `struct sockaddr_in', `struct sockaddr_un', etc.  */
 34
 35 #define __SOCKADDR_COMMON(sa_prefix) /
 36   sa_family_t sa_prefix##family
 37
 38 #define __SOCKADDR_COMMON_SIZE  (sizeof (unsigned short int))


 39
 40 #endif  /* bits/sockaddr.h */

 //////////////////////////////////////////////////////////////////////////////////
 //include/bits/socket.h
 21 #ifndef __BITS_SOCKET_H
 22 #define __BITS_SOCKET_H
 23
 24 #ifndef _SYS_SOCKET_H
 25 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 26 #endif
 27
 28 #define __need_size_t
 29 #include <stddef.h>
 30
 31 #include <sys/types.h>
 32
 33 /* Type for length arguments in socket calls.  */
 34 #ifndef __socklen_t_defined
 35 typedef __socklen_t socklen_t;
 36 # define __socklen_t_defined
 37 #endif
 38
 39 /* Types of sockets.  套接字类型*/
 40 enum __socket_type
 41 {
 42   SOCK_STREAM = 1,      /* Sequenced, reliable, connection-based
 43                    byte streams.  */
 44 #define SOCK_STREAM SOCK_STREAM
 45   SOCK_DGRAM = 2,       /* Connectionless, unreliable datagrams
 46                    of fixed maximum length.  */
 47 #define SOCK_DGRAM SOCK_DGRAM
 48   SOCK_RAW = 3,         /* Raw protocol interface.  */


 49 #define SOCK_RAW SOCK_RAW
 50   SOCK_RDM = 4,         /* Reliably-delivered messages.  */
 51 #define SOCK_RDM SOCK_RDM
 52   SOCK_SEQPACKET = 5,       /* Sequenced, reliable, connection-based,
 53                    datagrams of fixed maximum length.  */
 54 #define SOCK_SEQPACKET SOCK_SEQPACKET
 55   SOCK_DCCP = 6,        /* Datagram Congestion Control Protocol.  */
 56 #define SOCK_DCCP SOCK_DCCP
 57   SOCK_PACKET = 10,     /* Linux specific way of getting packets
 58                    at the dev level.  For writing rarp and
 59                    other similar things on the user level. */
 60 #define SOCK_PACKET SOCK_PACKET
 61
 62   /* Flags to be ORed into the type parameter of socket and socketpair and
 63      used for the flags parameter of paccept.  */
 64
 65   SOCK_CLOEXEC = 02000000,  /* Atomically set close-on-exec flag for the
 66                    new descriptor(s).  */
 67 #define SOCK_CLOEXEC SOCK_CLOEXEC
 68   SOCK_NONBLOCK = 04000     /* Atomically mark descriptor(s) as
 69                    non-blocking.  */
 70 #define SOCK_NONBLOCK SOCK_NONBLOCK
 71 };
 72
 73 /* Protocol families. 协议家族 */
 74 #define PF_UNSPEC   0   /* Unspecified.  */
 75 #define PF_LOCAL    1   /* Local to host (pipes and file-domain).  */
 76 #define PF_UNIX     PF_LOCAL /* POSIX name for PF_LOCAL.  */
 77 #define PF_FILE     PF_LOCAL /* Another non-standard name for PF_LOCAL.  */
 78 #define PF_INET     2   /* IP protocol family.  */
 
108 /* Address families. 地址家族,由协议家族决定 */
109 #define AF_UNSPEC   PF_UNSPEC
110 #define AF_LOCAL    PF_LOCAL
111 #define AF_UNIX     PF_UNIX
112 #define AF_FILE     PF_FILE
113 #define AF_INET     PF_INET

158 /* Get the definition of the macro to define the common sockaddr members.  */
159 #include <bits/sockaddr.h>
160
161 /* Structure describing a generic socket address.  */
162 struct sockaddr
163   {
164     __SOCKADDR_COMMON (sa_);    /* Common data: address family and length. 这里引用了bits/sockaddr.h文件里面的定义 */
165     char sa_data[14];       /* Address data.  */
166   };
167 //这个结构是最基本的套接字结构,共16个字节,前两个字节为地址家族,后面的14个字节是具体的地址值


194 #endif  /* bits/socket.h */

/////////////////////////////////////////
//sys/socket.h
/* Declarations of socket constants, types, and functions. */
 20
 21 #ifndef _SYS_SOCKET_H
 22 #define _SYS_SOCKET_H   1
 23
 24 #include <features.h>
 25
 26 __BEGIN_DECLS
 27
 28 #include <sys/uio.h>
 29 #define __need_size_t
 30 #include <stddef.h>
 31 #ifdef __USE_GNU
 32 /* Get the __sigset_t definition.  */
 33 # include <bits/sigset.h>
 34 #endif
 35
 36
 37 /* This operating system-specific header file defines the SOCK_*, PF_*,
 38    AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr',
 39    `struct msghdr', and `struct linger' types.  */
 40 #include <bits/socket.h>
 41
 42 #ifdef __USE_BSD
 43 /* This is the 4.3 BSD `struct sockaddr' format, which is used as wire
 44    format in the grotty old 4.3 `talk' protocol.  */
 45 struct osockaddr
 46   {
 47     unsigned short int sa_family;
 48     unsigned char sa_data[14];
 49   };
 50 #endif

 64 /* This is the type we use for generic socket address arguments.
       With GCC 2.7 and later, the funky union causes redeclarations or
 67    uses with any of the listed types to be allowed without complaint.
 68    G++ 2.7 does not support transparent unions so there we want the
 69    old-style declaration, too.
       G++ 2.7版本以前,都是严格使用的sockaddr地址数据结构,不支持其他数据结构 
    */
 70 #if defined __cplusplus || !__GNUC_PREREQ (2, 7) || !defined __USE_GNU
 71 # define __SOCKADDR_ARG     struct sockaddr *__restrict
 72 # define __CONST_SOCKADDR_ARG   __const struct sockaddr *
 73 #else
 74 /* Add more `struct sockaddr_AF' types here as necessary.
 75    These are all the ones I found on NetBSD and Linux.  */
    /*定义所有的地址家族的地址数据结构*/
 76 # define __SOCKADDR_ALLTYPES /
 77   __SOCKADDR_ONETYPE (sockaddr) /     //我们早期使用的ipv4地址数据结构,所有的socket函数都使用这种类型, 但是该类型不好赋值,所以我们用sockaddr_in数据结构取代他,之所以没有取消这种结构, 我觉得应该是考虑早期兼容的问题。
 78   __SOCKADDR_ONETYPE (sockaddr_at) /
 79   __SOCKADDR_ONETYPE (sockaddr_ax25) /
 80   __SOCKADDR_ONETYPE (sockaddr_dl) /
 81   __SOCKADDR_ONETYPE (sockaddr_eon) /
 82   __SOCKADDR_ONETYPE (sockaddr_in) /  //我们现在使用的ipv4地址数据结构
 83   __SOCKADDR_ONETYPE (sockaddr_in6) /
 84   __SOCKADDR_ONETYPE (sockaddr_inarp) /
 85   __SOCKADDR_ONETYPE (sockaddr_ipx) /
 86   __SOCKADDR_ONETYPE (sockaddr_iso) /
 87   __SOCKADDR_ONETYPE (sockaddr_ns) /
 88   __SOCKADDR_ONETYPE (sockaddr_un) /
 89   __SOCKADDR_ONETYPE (sockaddr_x25)
 90
 91 # define __SOCKADDR_ONETYPE(type) struct type *__restrict __##type##__;
    //宏定义:假设type为sockaddr_in 则__SOCKADDR_ONETYPE(type) 为   struct sockaddr_in  *  __restrict __sockaddr_in __;

102 /* Create a new socket of type TYPE in domain DOMAIN, using
     protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
     Returns a file descriptor for the new socket, or -1 for errors. 
      创建socket函数
    */
105 extern int socket (int __domain, int __type, int __protocol) __THROW;


106
107 /* Create two new sockets, of type TYPE in domain DOMAIN and using
108    protocol PROTOCOL, which are connected to each other, and put file
109    descriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,
110    one will be chosen automatically.  Returns 0 on success, -1 for errors.  */
111 extern int socketpair (int __domain, int __type, int __protocol,
112                int __fds[2]) __THROW;
113
114 /* Give the socket FD the local address ADDR (which is LEN bytes long).  */
 /* 将本地地址绑定到套接字上*/
115 extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
116      __THROW;


117
118 /* Put the local address of FD into *ADDR and its length in *LEN.  */
    /* 将本地套接字中的地址提取到Addr和LEN中,和上面的比较,可以知道输入参数不加指针,输出参数通过指针实现*/
119 extern int getsockname (int __fd, __SOCKADDR_ARG __addr,
120             socklen_t *__restrict __len) __THROW;
121
122 /* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
123    For connectionless socket types, just set the default address to send to
124    and the only address from which to accept transmissions.
125    Return 0 on success, -1 for errors.
126    建立到远程服务器的链接,将本地套接字和远程服务器地址隐式绑定,所以客户端必须事先知道服务器地址,才能链接,注意上面的bind是将服务器套接字显示绑定到服务器地址上。
127    This function is a cancellation point and therefore not marked with
128    __THROW.  */
129 extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
130
131 /* Put the address of the peer connected to socket FD into *ADDR
132    (which is *LEN bytes long), and its actual length into *LEN.  */
    /*客户端从fd中获取远程链接地址和长度*/
133 extern int getpeername (int __fd, __SOCKADDR_ARG __addr,
134             socklen_t *__restrict __len) __THROW;
135
136
137 /* Send N bytes of BUF to socket FD.  Returns the number sent or -1.
138
139    This function is a cancellation point and therefore not marked with
140    __THROW.  */
141 extern ssize_t send (int __fd, __const void *__buf, size_t __n, int __flags);
142
143 /* Read N bytes into BUF from socket FD.
144    Returns the number read or -1 for errors.
145
146    This function is a cancellation point and therefore not marked with
147    __THROW.  */
148 extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);
149
150 /* Send N bytes of BUF on socket FD to peer at address ADDR (which is
151    ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.
152
153    This function is a cancellation point and therefore not marked with
154    __THROW.  */
155 extern ssize_t sendto (int __fd, __const void *__buf, size_t __n,
156                int __flags, __CONST_SOCKADDR_ARG __addr,
157                socklen_t __addr_len);
158
159 /* Read N bytes into BUF through socket FD.
160    If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of
161    the sender, and store the actual size of the address in *ADDR_LEN.
162    Returns the number of bytes read or -1 for errors.
163
164    This function is a cancellation point and therefore not marked with
165    __THROW.  */
166 extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,
167              int __flags, __SOCKADDR_ARG __addr,
168              socklen_t *__restrict __addr_len);
169
170
171 /* Send a message described MESSAGE on socket FD.
172    Returns the number of bytes sent, or -1 for errors.
173
174    This function is a cancellation point and therefore not marked with
175    __THROW.  */
176 extern ssize_t sendmsg (int __fd, __const struct msghdr *__message,
177             int __flags);
178
179 /* Receive a message as described by MESSAGE from socket FD.
180    Returns the number of bytes read or -1 for errors.
181
182    This function is a cancellation point and therefore not marked with
183    __THROW.  */
184 extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags);
185
186
187 /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL
188    into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's
189    actual length.  Returns 0 on success, -1 for errors.  */
190 extern int getsockopt (int __fd, int __level, int __optname,
191                void *__restrict __optval,
192                socklen_t *__restrict __optlen) __THROW;
193
194 /* Set socket FD's option OPTNAME at protocol level LEVEL
195    to *OPTVAL (which is OPTLEN bytes long).
196    Returns 0 on success, -1 for errors.  */
197 extern int setsockopt (int __fd, int __level, int __optname,
198                __const void *__optval, socklen_t __optlen) __THROW;
199
200
201 /* Prepare to accept connections on socket FD.
202    N connection requests will be queued before further requests are refused.
203    Returns 0 on success, -1 for errors. 
       准备在监听套接字FD上监听链接,链接最大数为__n
    */
204 extern int listen (int __fd, int __n) __THROW;
205
206 /* Await a connection on socket FD.
207    When a connection arrives, open a new socket to communicate with it,
208    set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
209    peer and *ADDR_LEN to the address's actual length, and return the
210    new socket's descriptor, or -1 for errors.
211    在监听套接字上等待链接,一旦有链接,则将客户端的地址和地址长度保存在__addr和__addr_len中。
212    This function is a cancellation point and therefore not marked with
213    __THROW.  */
214 extern int accept (int __fd, __SOCKADDR_ARG __addr,
215            socklen_t *__restrict __addr_len);
216
217 /* Shut down all or part of the connection open on socket FD.
218    HOW determines what to shut down:
219      SHUT_RD   = No more receptions;
220      SHUT_WR   = No more transmissions;
221      SHUT_RDWR = No more receptions or transmissions.
222    Returns 0 on success, -1 for errors.  */
223 extern int shutdown (int __fd, int __how) __THROW;
244
245 __END_DECLS
246
247 #endif /* sys/socket.h */

//////////////////////////////////////////////////////////////////////////////
//include/netinet/in.h
//该文件包含了包含Internet Address等一些列的IP协议,端口,A/B/C/D四类地址,回环地址/INADDR_ANY/INADDR_BROADCAST地址, IP地址数据结构,socket地址数据结构(定义在Ip地址基础上),
//以及字节序转换函数,同时因为包含了sys/socket.h,所以包含该文件,基本上就能进行网络编程。


#ifndef _NETINET_IN_H
#define _NETINET_IN_H   1

#include <features.h>
#include <stdint.h>
#include <sys/socket.h>

//sys/socket.h包含了所有网络通讯的函数和常量以及基本数据结构 ,通过包含bits/socket.h,获得了SOCK_* PF_*,AF_*等常量,以及sockaddr——最基本的socket地址数据结构。本身包含了所有的外部接口函数如socket,bind,listen,accept,send,recv等

#include <bits/types.h>

__BEGIN_DECLS

/* Standard well-defined IP protocols.
  定义IP协议类型
*/
enum
  {
    IPPROTO_IP = 0,    /* Dummy protocol for TCP.  */
#define IPPROTO_IP      IPPROTO_IP
    IPPROTO_HOPOPTS = 0,   /* IPv6 Hop-by-Hop options.  */
#define IPPROTO_HOPOPTS     IPPROTO_HOPOPTS
    IPPROTO_ICMP = 1,      /* Internet Control Message Protocol.  */
#define IPPROTO_ICMP        IPPROTO_ICMP
    IPPROTO_IGMP = 2,      /* Internet Group Management Protocol. */
#define IPPROTO_IGMP        IPPROTO_IGMP
    IPPROTO_IPIP = 4,      /* IPIP tunnels (older KA9Q tunnels use 94).  */
#define IPPROTO_IPIP        IPPROTO_IPIP
    IPPROTO_TCP = 6,       /* Transmission Control Protocol. TCP协议 */
#define IPPROTO_TCP     IPPROTO_TCP
  
  };

/* 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. FTP协议端口为21 */
    IPPORT_TELNET = 23,     /* Telnet protocol.  TELNET协议端口为23*/
    IPPORT_SMTP = 25,       /* Simple Mail Transfer Protocol. 简单邮件协议端口为25 */
    IPPORT_TIMESERVER = 37, /* Timeserver service.  */
    IPPORT_NAMESERVER = 42, /* Domain Name Service. DNS协议端口为42 */


    IPPORT_WHOIS = 43,      /* Internet Whois service.  */
    IPPORT_MTP = 57,

    /* Ports less than this value are reserved for privileged processes. 端口号小于1024是系统进程保留的端口 */
    IPPORT_RESERVED = 1024,

    /* Ports greater this value are reserved for (non-privileged) servers.端口大于5000的为用户进程端口号  */
    IPPORT_USERRESERVED = 5000

  }; 

 
/* Internet address.定义IPV4网络地址in 表示inter-net 首字母  */
 
typedef uint32_t in_addr_t;
 
struct in_addr
  {
    in_addr_t s_addr;
  };

/* Definitions of the bits in an Internet address integer.
    定义A/B/C/D四类网络地址,网络地址分为主机部分和网络部分,根据子网掩码可以获得相应的部分的值。
   On subnets, host and network parts are found according to
   the 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

/* Address to accept any incoming messages. 此地址用来接受任意网络地址的信息,0x00000000值即表示整个意思 */
#define INADDR_ANY      ((in_addr_t) 0x00000000)
/* Address to send to all hosts.  此地址可以用来向任意网络地址的主机发送信息,0xffffffff值即表示整个意思 */
#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


/* Structure describing an Internet socket address. IPv4协议的套接字地址定义之所以为*_in是为了表示该地址是IPv4协议下的地址,和IPv6区分开*_in6) */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);   /*协议族*/
    in_port_t sin_port;         /* Port number.  */
    struct in_addr sin_addr;    /* Internet address.  */

    /*
    struct sockaddr
    {
      __SOCKADDR_COMMON (sa_);   
             char sa_data[14];     
    };
    */

    /* Pad to size of `struct sockaddr'.  sockaddr一般为16个字节,剩余的空间填充0,这样保持这两种数据类型长度一致,便于进行类型转换*/
    unsigned char sin_zero[sizeof (struct sockaddr) -
               __SOCKADDR_COMMON_SIZE -
               sizeof (in_port_t) -
               sizeof (struct in_addr)];
  };

/* 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 */
  };

/* Get system-specific definitions.  */
#include <bits/in.h>

/* 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.  But
   this was a short-sighted decision since on different systems the types
   may 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>

#ifdef __OPTIMIZE__ //使用优化的转换函数对字节序进行转换
/* We can optimize calls to the conversion functions.  Either nothing has
   to be done or we are using directly the byte-swapping functions which
   often 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)   (x)
# define ntohs(x)   (x)
# define htonl(x)   (x)
# define htons(x)   (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

抱歉!评论已关闭.