在socket网络编程中经常用到一些宏定义、结构和函数,这些经常包含在相关的头文件中,使用时直接include相关头文件即可。下面简单描述下相关的一些结构及头文件。

1. sockaddr  / bits/socket.h

socket编程最基本的就是socket地址,其定义在bits/socket.h中。但sys/socket.h包含bits/socket.h,且bits/socket.h明确指出该头文件不能直接使用,应使用sys/socket.h代替。

struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[]; /* Address data. */
};

其中__SOCKADDR_COMMON()宏定义在bits/sockaddr.h中

#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family #define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))

替换后为

struct sockaddr{
unsigned short sa_family;
char sa_data[];
};

在bits/socket.h中还定义了协议族(Protocol families,PF_xxx)和地址族(Address families,AF_xx),两者一一对应,因此可以互换,应用场合根据概念稍有不同。

#define PF_UNSPEC   0   /* Unspecified.  */
#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */
#define PF_UNIX PF_LOCAL /* POSIX name for PF_LOCAL. */
#define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */
#define PF_INET 2 /* IP protocol family. */
#define PF_AX25 3 /* Amateur Radio AX.25. */
#define PF_IPX 4 /* Novell Internet Protocol. */
#define PF_APPLETALK 5 /* Appletalk DDP. */ #define PF_INET6 10 /* IP version 6. */ #define PF_LLC 26 /* Linux LLC. */
#define PF_CAN 29 /* Controller Area Network. */ #define PF_NFC 39 /* NFC sockets. */
#define PF_VSOCK 40 /* vSockets. */
#define PF_MAX 41 /* For now.. */

2. sys/socket.h

该头文件包含常用的socket编程函数接口,如:

socket() bind() listen() connect() accept() shutdown()

send() recv() sendto() recvfrom() sendmsg() recvmsg() sendmmsg() recvmmsg()

socketpair() getsockname() getpeername()

getsockopt() setsockopt()

除此外,sys/socket.h包含bits/socket.h,需要bits/socket.h的函数直接include sys/socket.h即可。

3. 网络socket地址 sockaddr_in -- netinet/in.h

与internet网络相关的头文件大部分在netinet目录下,如in.h ip.h(ip协议相关数据结构) tcp.h(tcp协议) udp.h(udp协议) ip_icmp.h(icmp协议) ip6.h icmp6.h等。

在网络编程中用到的socket地址是经过转换的网络socket地址sockaddr_in:

/* Structure describing an Internet socket address.  */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_); /* unsigned short sin_family; */
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)];
};

网络地址

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};

网络端口

/* Type to represent a port.  */
typedef uint16_t in_port_t;

据此也可推断出:唯一确定一个连接(socket)的五要素:目的IP,目的端口,源IP,源端口,协议。

经典的4个主机网络字节序转换函数

/* 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__));

netinet/in.h定义了标准协议enum:

enum
{
IPPROTO_IP = , /* Dummy protocol for TCP. */
#define IPPROTO_IP IPPROTO_IP
IPPROTO_ICMP = , /* Internet Control Message Protocol. */
#define IPPROTO_ICMP IPPROTO_ICMP
IPPROTO_IGMP = , /* Internet Group Management Protocol. */
#define IPPROTO_IGMP IPPROTO_IGMP
IPPROTO_IPIP = , /* IPIP tunnels (older KA9Q tunnels use 94). */
#define IPPROTO_IPIP IPPROTO_IPIP
IPPROTO_TCP = , /* Transmission Control Protocol. */
#define IPPROTO_TCP IPPROTO_TCP
IPPROTO_EGP = , /* Exterior Gateway Protocol. */
#define IPPROTO_EGP IPPROTO_EGP
IPPROTO_PUP = , /* PUP protocol. */
#define IPPROTO_PUP IPPROTO_PUP
IPPROTO_UDP = , /* User Datagram Protocol. */
#define IPPROTO_UDP IPPROTO_UDP
IPPROTO_IDP = , /* XNS IDP protocol. */ IPPROTO_IPV6 = , /* IPv6 header. */
#define IPPROTO_IPV6 IPPROTO_IPV6
    IPPROTO_RAW = 255,     /* Raw IP packets.  */
#define IPPROTO_RAW     IPPROTO_RAW
    IPPROTO_MAX
};

标准端口enum

enum
{
IPPORT_ECHO = , /* Echo service. */
IPPORT_DISCARD = , /* Discard transmissions service. */
IPPORT_SYSTAT = , /* System status service. */
IPPORT_DAYTIME = , /* Time of day service. */
IPPORT_NETSTAT = , /* Network status service. */
IPPORT_FTP = , /* File Transfer Protocol. */
IPPORT_TELNET = , /* Telnet protocol. */
IPPORT_SMTP = , /* Simple Mail Transfer Protocol. */
IPPORT_TIMESERVER = , /* Timeserver service. */
IPPORT_NAMESERVER = , /* Domain Name Service. */
IPPORT_WHOIS = , /* Internet Whois service. */
IPPORT_MTP = , IPPORT_TFTP = , /* Trivial File Transfer Protocol. */
IPPORT_RJE = ,
IPPORT_FINGER = , /* Finger service. */
IPPORT_TTYLINK = ,
IPPORT_SUPDUP = , /* SUPDUP protocol. */ IPPORT_EXECSERVER = , /* execd service. */
IPPORT_LOGINSERVER = , /* rlogind service. */
IPPORT_CMDSERVER = ,
IPPORT_EFSSERVER = , /* UDP ports. */
IPPORT_BIFFUDP = ,
IPPORT_WHOSERVER = ,
IPPORT_ROUTESERVER = , /* Ports less than this value are reserved for privileged processes. */
IPPORT_RESERVED = , /* Ports greater this value are reserved for (non-privileged) servers. */
IPPORT_USERRESERVED =
};

ABCD四类网络,常用IP地址

#define IN_CLASSA(a)        ((((in_addr_t)(a)) & 0x80000000) == 0)

#define IN_CLASSB(a)        ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)

#define IN_CLASSC(a)        ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)

#define IN_CLASSD(a)        ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)

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

还有IPv6、filter相关结构及函数。

4. 网络地址二进制与字符串转换 -- arpa/inet.h

推荐使用inet_pton()或inet_aton(),而非inet_addr()或inet_network(),因为返回值-1代表IP地址255.255.255.255。

extern int inet_aton (const char *__cp, struct in_addr *__inp) __THROW;
extern char *inet_ntoa (struct in_addr __in) __THROW; /* Convert from presentation format of an Internet number in buffer
starting at CP to the binary network format and store result for
interface type AF in buffer starting at BUF. */
extern int inet_pton (int __af, const char *__restrict __cp,
void *__restrict __buf) __THROW; /* Convert a Internet address in binary network format for interface
type AF in buffer starting at CP to presentation form and place
result in buffer of length LEN astarting at BUF. */
extern const char *inet_ntop (int __af, const void *__restrict __cp,
char *__restrict __buf, socklen_t __len) __THROW;
#define servip "192.168.1.103"

inet_pton(AF_INET, servip, &servaddr.sin_addr.s_addr);

实现二进制网络ip与字符串ip之间的转换,均以inet开头。

此外arpa还包含ftp.h tftp.h telnet.h nameser.h nameser_compat.h。

5. netdb.h -- network data base library

/* All data returned by the network data base library are supplied in
host order and returned in network order (suitable for use in
system calls). */

提供主机/域名等结构体或函数。

/* 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. */
#if defined __USE_MISC || defined __USE_GNU
# define h_addr h_addr_list[] /* Address, for backward compatibility.*/
#endif
};
/* 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. */
};
/* 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. */
};

提供的常用函数:

extern struct hostent *gethostent (void);
extern struct hostent *gethostbyaddr (const void *__addr, __socklen_t __len,
int __type);
extern struct hostent *gethostbyname (const char *__name); extern struct servent *getservbyname (const char *__name, const char *__proto);
extern struct servent *getservbyport (int __port, const char *__proto); extern struct protoent *getprotobyname (const char *__name);
extern struct protoent *getprotobynumber (int __proto);

6. sys/un.h--unix域头文件

un.h中包含Unix域套接字的地址结构体sockaddr_un。

#include <sys/un.h>

#define UNIX_PATH_MAX   108

struct sockaddr_un {
__kernel_sa_family_t sun_family; /* AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* pathname */
};

实际地址长度为:offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1

socket编程头文件分析的更多相关文章

  1. Android JNI入门第三篇——jni头文件分析

    一. 首先写了java文件: public class HeaderFile { private native void  doVoid(); native int doShort(); native ...

  2. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

  3. linux内核中链表代码分析---list.h头文件分析(二)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...

  4. openCV之头文件分析

    我们利用openCV开源库进行项目开发时,往往要牵涉到头文件的添加问题,而openCV中头文件众多,该如何选择呢?下面对openCV2.4.10的头文件进行一个简单的梳理,以便能够快速的添加对应的头文 ...

  5. linux编程头文件所在路径的问题

    一.问题引入 1.头文件与库 当我们在PC主机linux环境下(如ubuntu),编写linux应用程序,然后利用gcc来编译.在源代码的开始位置会写入头文件,那是因为我们使用了系统提供的库函数,例如 ...

  6. Unix网络编程 — 头文件解析

    1.1. < sys/types.h > primitive system data types(包含很多类型重定义,如pid_t.int8_t等) 1.2. < sys/socke ...

  7. 记一次:Windows的Socket编程学习和分析过程

    Socket编程依赖于:WS2_32.dll --- 服务端 --- .导入我们需要的函数 #incldue <windows.h> //#include<WinSock2.h> ...

  8. windows 编程—— 头文件 指引

    定义    相关头文件 #define UNICODE  <WINUSER.h> <WINNT.h>  <WINBASE.h> #define _UNICODE   ...

  9. linux c 编程 ------ 头文件及其作用

    #include <stdio.h> printf #include <sys/types.h> 基本系统数据类型.系统的基本数据类型在32编译环境中保持为32位值,在64编译 ...

随机推荐

  1. 纯CSS实现多行文字垂直居中几种方法解析

    场景:父元素 高度固定,如何使其中的文字垂直居中? 1.table布局: 利用display:table+display:table-cell的方法 <!DOCTYPE html> < ...

  2. Java自定义注解基础知识

    注解分为三类:没有任何元素的注解,有一个元素的注解和有多个元素的注解. 1. Marker注解 这类注解没有任何元素,此类注解仅仅是一个标示.如下所示: public @interface Good ...

  3. Python函数:使用谷歌翻译翻译英语字符串

    代码是同事写的,我把它单独抠出来,可以作为工具函数使用.当然,性能还是个问题,有待解决. import random import cookielib import urllib import url ...

  4. 【转】Android一些知识点汇总

    Android常用知识点总汇 一.系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由. 如果在你的android系统上安装了多种浏览器,能否指定某浏览器访问指定页面?答案当然是:肯定的. ...

  5. Redis 数据结构之简单动态字符串SDS

    几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象.    ...

  6. Orange的数据挖掘工具入门使用

    Orange的数据挖掘工具入门使用 声明: 1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途. 2)若本文档内有侵权文字或图片等内容,请联系作者bitpeach ...

  7. 批量部署 自动化之 - [pssh](转)

    并行执行命令工具简介 作为运维工程师来讲,机器数量到一定级别的时候,批量运维和管理机器就是一件费神的事情,还好有很多可以批量并行执行命令的工具,比如 pssh , python fabrictaoba ...

  8. javascript Array(数组)

      迁移时间:2017年5月25日08:05:33 UpdateTime--2017年3月31日16:29:08 一.数组(Array) (一)用法 //js声明数组的两大类方式 // 第一类(通常使 ...

  9. Android推送方案

    一. 常见的推送原理: 1)轮询(Pull)方式:应用程序应当阶段性的与服务器进行连接并查询是否有新的消息到达,你必须自己实现与服务器之间的通信,例如消息排队等.而且你还要考虑轮询的频率,如果太慢可能 ...

  10. C++ opencv高速样例学习——读图显示

    1.关键函数 1. 读入图片 imread(图片或位置,显示格式)默觉得:IMREAD_COLOR 显示格式: IMREAD_UNCHANGED =-1    // 8bit, color or no ...