第3章 套接字地址结构

  • Post author:
  • Post category:其他



目录


1. 套接字地址结构


2. 值-结果参数


3. 字节排序函数


4. 字节操纵函数


5. inet_aton、inet_addr、inet_ntoa函数


6. inet_pton、inet_ntop 函数


7. read和write



1. 套接字地址结构

每个协议族都定义了它自己的套接字地址结构。


(1) IPv4

然而,当我们打开自己本地(Linux 系统)的 in.h,看到这样:

为什么会这样定义,这是有历史原因的,我们看到有一个 “struct sockaddr”,这是一个通用套接字地址结构,我们使用的套接字函数,如bind(),就会用到这个类型的参数。因为是通用结构,所以代表了很多协议的套接字地址结构,我们可以在/usr/lib/bits/socket.h中找到这个定义:

长度字段 sin_len 是为了增加对OSI协议的支持而随 4.3BSD-Reno 添加的,并不是所有厂家都支持,而且POSIX也不要求。


(2) IPv6


(3) 下图展示的是贯穿该书中的套接字地址结构的比较



2. 值-结果参数

(1) 从进程到内核传递套接字地址结构的函数有3个:bind、connect、sendto。如下:

struct sockaddr_in serv;
connect(sockfd, (SA *)&serv, sizeof(serv));

这样,指针和指针所指内容的大小都传递给了内核,于是内核就知道了从进程复制多少数据进来。

(2) 从内核到进程传递套接字地址结构的函数有4个:accept、recvfrom、getsockname、getpeername。

struct sockaddr_un cli;
socklen_t len;
len = sizeof(cli);
getpeername(unixfd, (SA *)&cli, &len);


3. 字节排序函数

术语“大端”和“小端”表示多个字节值的哪一端(大端或小端)存储在改值的起始地址处。这两种格式都有系统使用,我们把某个给定系统所使用的字节序称为主机字节序。

主机字节序和网络字节序的转换函数:



4. 字节操纵函数

(1) 以空字节结尾的C字符串是由在<string.h>头文件中定义、名字以 str(表示字符串)开头的函数处理的。

(2) 名字以 b(表示字节)开头的函数,起源于4.2BSD,几乎所有现今支持套接字函数的系统仍然提供他们。

(3) 名字以 mem(表示内存)开头的第一组函数起源于ANSI C标准,支持ANSI C函数库的所有系统都提供他们。



5. inet_aton、inet_addr、inet_ntoa函数

这些函数提供这样的功能:在点分十进制数串(”206.168.112.96″)与它长度为32位的网络字节序二进制值间转换IPv4地址。

注意:inet_addr 由于有局限性,所以现在编程应该弃用,新的代码应该使用 inet_aton 函数。或者使用下面的函数,他们还支持IPv6。inet_ntoa 是不可重入函数,由于不可重入的函数使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的。所以还是尽量使用下面的函数。



6. inet_pton、inet_ntop 函数

注意:inet_ntop() 函数的 len 参数,其值对于 IPv4 最小为16,对于 IPv6 最小为46,这是因为包括了结尾的空字符,如果过小,该函数会将 errno 置 ENOSPC。



7. read和write

当我们建立了字节流套接字,就可以使用系统函数read和write来进行读写操作了。



版权声明:本文为lc250123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。