这里的基础并不是针对所有人的,而是针对刚刚入门的菜鸟。这些基础完全可以理解我们在实际网络编程中所需要关注的一些注意事项。
1、套接字是端到端的服务,向用户屏蔽了中间的传输过程,比如中间的路由节点,这里的用户指的是进程。
2、端口采用全局分配和动态分配相结合的分配方式:全局分配由公认的机构统一分配,叫做知名端口,是0~1023,常用的服务都是这种分配方式,基本上每个端口都绑定了一个知名的服务,如HTTP协议为80端口。另外,可简单的把剩下的1024~65535认为是动态分配,供应用进程灵活使用,这些端口仍然可以绑定知名服务。
3、在网络上标识一个通信进程需要一个半相关:IP地址+端口号+协议。因此一个完整的端到端由一个全相关组成:协议+本地IP地址+本地端口+远程IP地址+远程端口。套接字地址是一个半相关,结构如下:
struct sockaddr_in{
u_short sin_family; 协议族类型
u_short sin_port; 端口号
struct in_addr sin_addr; IP地址
char sin_zero[8]; 保留,没有使用 }
其中IP地址的结构如下:
struct in_addr{
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
}
4、sockaddr与sockaddr_in之间可以进行强制类型转换。前者没有具体定义端点中的端口及地址的详细内容,会在某些socket函数中使用。个人认为使用这个结构主要是为了使结构体能适用于多种协议。
struct sockaddr{
u_short sa_family;
char sa_data[14];
}
5、系统通过套接字描述符来对应套接口结构,通常进程所获得只是套接字描述符,然后通过一系列socket函数来对其对应的套接口进行操作。套接字描述符是局部分配,套接口资源是全局分配。因此,可能出现不同进程里面存在相同的套接字描述符,对应于不同的套接口资源。从网络来的数据包的处理过程:tcp实体根据报文中的端口信息,根据端口找到对应的套接口结构,然后将报文挂在与端口绑定的套接口接收队列中,进程从套接口的接收队列中取得报文。
6、套接字描述符、套接口结构和端口是相对独立的三个概念,一般是一一对应的。一个套接字标识符在调用socket后对应于一个套接口结构,该套接口结构在bind以后工作在确定的端口上,在connect后,对方端点也确定下来了。
7、低地址存数据的低位是little endian系统,典型的是INTEL。低地址存数据的高位是big endian系统,典型的是MOTO。因此,两者之间的通信需要按照规定的传输顺序:先传高字节,这实际上是规定了缓冲区数据的放置顺序,因为发送的处理顺序是从低地址处理到高地址。因此,对于Big endian系统,放置和取出的顺序不用改变,对于Little endian系统,放置和取出的顺序必须和普通情况下不同。由系统提供htonx和ntohx的实现,网络软件在任何时候需要向数据缓冲区内存放(读取)整数时必须使用以上函数。由于不同的系统提供不同的实现方式,用户网络软件不再需要考虑字节序的不一致和程序移植问题。
该资料参考了本科时候的课件,在这里再次感谢兢兢业业的老师,制作了非常有价值的课件。