问题聚焦:
这节介绍的不仅是网络编程的几个API
更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系。
这节主要介绍三个方面的内容:套接字(socket地址)API,socket基础API,和网络信息API。
套接字API
套接字socket:(ip, port),即IP地址和端口对,唯一地表示了使用该TCP通信的一端。
需要了解:主机字节序和网络字节序。
原因:考虑32位的机器,CPU的累加器一次装载4字节的内容。那么这4字节在内存中的顺序将影响它被累加器装载后的所代表的含义。
分类:
- 大端字节序:“高低,低高”,即,一个整数的高位字节(23~31位)存储在内存的低地址处,低位字节存储在内存的高地址处。
- 小端字节序:“高高,低低”。
主机字节序:小端字节序。
网络字节序:大端字节序。
存在的问题:并不是所有的机器都采用主机字节序。一旦收发双方的字节序不同,必然导致错误的接收。
解决方法:发送端总是把要发送的数据转化成大端字节序,再发送。
注意:即使同一台机器上的两个进程,也要考虑字节序的问题,如一个客户端使用C语言编写,而另一个采用java编写(java虚拟机使用大端字节序)。
Linux提供的转换函数:
#inlcude<netinet/in.h>
unsigned long int htonl( unsigned long int hostlong );
unsigned short int htons( unsigned short int hostshort );
unsigned long int ntohl( unsigned long int netlong );
unsigned short int ntohs( unsigned short int netshort );
通用socket地址(结构体)
#include <bits/socket.h>
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
}
sa_family_da:地址族类型,与协议族类型对应。取值和对应关系如下图所示:
sa_data(char):存放socket地址。
协议族及其地址值:
数组长度有限,所以Linux提供了下面的新的
通用socket地址结构体。
#include <bits/socket.h>
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ssalign;
char __ss_padding[128-sizeof(__ss__align)];
}
__ss__align成员的作用:内存对齐。