在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. Neo4J简单了解

    1.什么是Neo4j Neo4j是由java实现的开源NOSQL图数据库 数据库分为关系型和非关系型两种类型. 其中非关系型又分为Graph(图形),Document(文档),Cloumn Famil ...

  2. 【笔记】探索js 的this 对象 (第三部分)

    了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后 最后一部分,来了解一下this 的一些例外情况 1.被忽略的this 例如在使用bind 方法时 ...

  3. mysql结构相同的三张表查询一条记录\将一张表中的数据插入另外一张表

    将一张表中的数据插入另外一张表 1.两张表结构相同 insert into 表1名称 select * from 表2名称 2.两张结构不相同的表 insert into 表1名称(列名1,列名2,列 ...

  4. tomcat中server.xml配置详解(转载)(一)

    转载自:https://www.cnblogs.com/starhu/p/5599773.html tomcat中server.xml配置详解 Tomcat Server的结构图如下:(该文件描述了如 ...

  5. python __slot__

    class Player(object): def __init__(self,name,age,life): self.name=name self.age=age self.life=life c ...

  6. taro 请求函数封装

    1.项目目录 2.代码 app/src/service/api.js import Taro from '@tarojs/taro' import { HTTP_STATUS } from '../c ...

  7. 001-使用idea开发环境安装部署,npm工具栏,脚本运行

    一.概述 参看官方文档:https://ant.design/docs/spec/introduce-cn 其中包含了设计价值观.设计原则.视觉.模式.可视化.动态等. 其中Ant Design 的 ...

  8. ES6 对象转Map

    使用Object.entries const obj = { foo: 'bar', baz: 42 }; const map = new Map(Object.entries(obj)); map ...

  9. javascript对于0的解读

      CreateTime--2017年6月29日10:36:01Author:Marydon javascript对于0的解读 1.0与“0” 1.1 判断0与"0"是否相等 测试 ...

  10. 09-spring学习-资源访问接口

    目标: 1,掌握Resource接口的使用. 2,掌握ResourceLoader接口的使用. 3,掌握各种资源数据的读取操作. 具体内容: 要想进行资源读取操作,首先想到IO包中提供的操作类. 但是 ...