linux网络编程之socket(一) socket概述和字节序、地址转换函数
一、什么是socket
socket可以看成是用户进程与内核网络协议栈的编程接口。 socket不仅可以用于本机的进 程间通信,还可以用于网络上不同主机的进程间通信。 socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及以后要讲的UNIX Domain Socket。然而,各种网络协议的地址格式并不相同,如下图所示: IPv4和IPv6的地址格式定义在netinet/in.h 中,IPv4地址用sockaddr_in结构体表示,包括16位端口号和32位IP地址,如下所示: struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ in_port_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ char sin_zero[8]; /* pad bytes, set to zero is ok */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ }; IPv6地址用sockaddr_in6结构体表示,包括16位端口号、128位IP地址和一些控制字段。UNIX Domain Socket的地址格式 定义在sys/un.h中,用sockaddr_un结构体表示。各种socket地址结构体的开头都是相同的,前16位表示整个结构体的长度 (并不是所有UNIX的实现都有长度字段,如Linux就没有),后16位表示地址类型。IPv4、IPv6和UNIX Domain Socket的地 址类型分别定义为常数AF_INET、AF_INET6、AF_UNIX。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪 种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。因此,socket API可以接受各种类型的sockaddr 结构体指针做参数,例如bind、accept、connect等函数,这些函数的参数应该设计成void *类型以便接受各种类型的指针 ,但是sock API的实现早于ANSI C标准化,那时还没有void *类型,因此这些函数的参数都用struct sockaddr *类型表示 ,即通用地址结构,如下所示: struct sockaddr { sa_family_t sin_family; char sa_data [14]; }; sin_family:指定该地址家族 sa_data:由sin_family决定它的形式。 在传递参数之前要强 制类型转换一下,例如: struct sockaddr_in servaddr; /* initialize servaddr * /bind(listen_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));
(编辑:佛山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |