TCP/IP协议规定,网络数据流应才使用大端字节序,即低地址高字节。
为使网络程序具有可移植性,使同样的C代码在大小端计算机上编译后都能正常运行,可以调用一下库函数做网络字节序和主机字节序的转换
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
h表示host。
n表示network。
l表示32位整数。
s表示16位短整数。
x
int main() {
int a = 0x12345678;
int b = htonl(a);
printf("a : %#x\nb : %#x\n", a, b);
short c = 0x1234;
short d = htons(c);
printf("c : %#x\nd : %#x\n", c, d);
return 0;
}
xxxxxxxxxx
a : 0x12345678
b : 0x78563412
c : 0x1234
d : 0x3412
xxxxxxxxxx
/* superset of previous */
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
raw_socket = socket(AF_INET, SOCK_RAW, protocol);
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 */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
xxxxxxxxxx
/* See NOTES */
int socket(int domain, int type, int protocol);
domain:通信的协议族;协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。可以选择以下:
xxxxxxxxxx
Name Purpose Man page
AF_UNIX Local communication unix(7)
AF_LOCAL Synonym for AF_UNIX
AF_INET IPv4 Internet protocols ip(7)
AF_AX25 Amateur radio AX.25 protocol ax25(4)
AF_IPX IPX - Novell protocols
AF_APPLETALK AppleTalk ddp(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_DECnet DECet protocol sockets
AF_KEY Key management protocol, originally de‐
veloped for usage with IPsec
AF_NETLINK Kernel user interface device netlink(7)
AF_PACKET Low-level packet interface packet(7)
AF_RDS Reliable Datagram Sockets (RDS) protocol rds(7)
rds-rdma(7)
AF_PPPOX Generic PPP transport layer, for setting
up L2 tunnels (L2TP and PPPoE)
AF_LLC Logical link control (IEEE 802.2 LLC)
protocol
AF_IB InfiniBand native addressing
AF_MPLS Multiprotocol Label Switching
AF_CAN Controller Area Network automotive bus
protocol
AF_TIPC TIPC, "cluster domain sockets" protocol
AF_BLUETOOTH Bluetooth low-level socket protocol
AF_ALG Interface to kernel crypto API
AF_VSOCK VSOCK (originally "VMWare VSockets") vsock(7)
protocol for hypervisor-guest communica‐
tion
AF_KCM KCM (kernel connection multiplexor) in‐
terface
AF_XDP XDP (express data path) interface
type:指定socket类型;有以下:
xxxxxxxxxx
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 packet with 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).
protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等。我们一般默认写0。
并不是上面的type和protocol可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默认协议。
xxxxxxxxxx
/* See NOTES */
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
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 */
};
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
xxxxxxxxxx
/* See NOTES */
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
xxxxxxxxxx
转换过来就是0.0.0.0,泛指本机的意思,也就是表示本机的所有IP,因为有些机子不止一块网卡,多网卡的情况下,这个就表示所有网卡ip地址的意思。
比如一台电脑有3块网卡,分别连接三个网络,那么这台电脑就有3个ip地址了,如果某个应用程序需要监听某个端口,那他要监听哪个网卡地址的端口呢?
如果绑定某个具体的ip地址,你只能监听你所设置的ip地址所在的网卡的端口,其它两块网卡无法监听端口,如果我需要三个网卡都监听,那就需要绑定3个ip,也就等于需要管理3个套接字进行数据交换,这样岂不是很繁琐?
所以出现INADDR_ANY,你只需绑定INADDR_ANY,管理一个套接字就行,不管数据是从哪个网卡过来的,只要是绑定的端口号过来的数据,都可以接收到。