套接字编程简介<一>

来源:互联网 发布:mac怎么切换中英文 编辑:程序博客网 时间:2024/05/12 20:20

具体请参见点击打开链接(https://github.com/uttp/UNIX-Network-Programming/blob/master/chapter3)


从第二部分基本套接字编程开始
第三章主要是套接字编程的简介,主要介绍了套接字编程后面要用到的主要函数
3.2节套接字地址结构


3.2.1 IPv4
套接字地址结构包含在头文件<netinet/in.h>中
struct in_addr
{
in_addr_t s_addr;
};
在其中in_addr_t一般为uint32_t(位整数,包含在头文件<sys/types.h>中)包含在头文件<netinet/in.h>中
struct scokaddr_in
{
uint8_t sin_len;     /*结构体的长度*/
sa_family_t sin_family;  /*AF_INET*/
in_port sin_port;    /*16-bit的tcp或者udp的端口号*/


struct in_addrsin_addr;   /*32位ipc4地址*/


char sin_zero[8]; /*保留未用*/
};


数据类型简要说明如下表
 +--------------+-------------------------+---------------+
 |  数据类型 |   说明 | 头文件    |
 +--------------+-------------------------+---------------+
 |  int8_t |   带符号的8位整数 | <sys/types.h> |
 |  uint8_t     |   无符号的8位整数  | <sys/types.h> |
 |  int16_t |   带符号的16位整数 | <sys/types.h> |
 |  uint16_t |   无符号的16位整数 | <sys/types.h> |
 |  int32_t |   带符号的32位整数 | <sys/types.h> |
 |  uint32_t |   无符号的32位整数 | <sys/types.h> |
 +--------------+-------------------------+---------------+
 |  sa_family_t |   套接字地址结构地址族  | <sys/socket.h>|
 |  socketlen_t |   套接字地址结构长度 | <sys/socket.h>|
 +--------------+-------------------------+---------------+
 |  in_addr_t |   IPV4地址,一般为32位 | <netinet/in.h>|
 |  in_port_t |   TCP或者UDP端口 | <netinet/in.h>|
 +--------------+-------------------------+---------------+


3.2.2通用套接字地址结构
当作通用套接字地址结构作为一个参数传递进任何套接字函数时,它总是以引用的形式来传递。这样以指针作为参数来传递的任何套接字函数必须处理来所
支持的任何协议族的套接字地址结构。
因此出现了定义通用的套接字地址结构,申明在头文件<sys/socket.h>中
struct sockaddr
{
uint8_t sa_len; /*结构体长度*/
sa_family_t sa_family; /*AF_INT*/
char sa_data/*协议地址*/
};
因此都需要进行强制转化为通用套接字地址结构
eg.  函数 int bind(int,struct sockaddr *, socklen_t);
当函数地址结构为
struct sockaddr_in serv;时就要进行如下的强制类型转化
bind(sockfd,(struct sockaddr *) &serv, sizeof(serv));


3.2.3IPv6套接字地址结构
IPv6套接字地址结构在头文件<netinet/in.h>中定义,定义结构如下
struct in6_addr
{
        uint8_t     s6_addr[16];
};


struct sockaddr_in6
{
        uint8_t         sin6_len;           /*结构体的长度*/
        sa_family_t     sin6_family         /*AF_INET6*/
in_port_t sin6_port


uint32_t sin6_flowinfo;
struct in6_addrsin6_addr;


uint32_t sin6_scope_id;
};


3.2.4新的通用套接字地址结构
struct sockaddr_storage
{
uint8_t ss_len;
sa_family_t ss_family;
/*用户透明部分*/
}


3.2.5套接字地址结构比较

IPv4 IPv6
sockaddr_in{} sockaddr_in6
  +-----+--------+                 +----+--------+
  | 长度|AF_INET |     |长度|AF_INT6 |
  +-----+--------+                 +----+--------+
  | 16位端口号 |    |16位端口号   |
  +--------------+                 +-------------+
  | 32位IPv4地址 |     |32位流标     |
  +--------------+                 +-------------+
  | 未用 |     |128位IPv6地址|
  +--------------+                 +-------------+
固定长度(16个字节)   |32位范围ID   |
              +-------------+
固定长度(28个字节)


3.3值-结果参数
套接字地址结构的传递方式有:从进程到内核和从内核到进程两种方式
(1)从进程到内核传递套接字地址结构的函数有3个:bind、connect、和sendto。
eg.struct sockaddr_in serv


connect(sockfd, (struct sockaddr*) &serv, sizeof(serv));


用户进程
+------------------------------------+
|   int                          |
|      +----+      +--------------+  |
|      |长度|      |套接字地址结构|  |
|      +-+--+      +-------+------+  |
|        |                 |         |
|     值 |                 |         |
|        |                 |         |
|        |                 |         |
|        |                 |         |
|     |     |协议地址 |
+--------+----+------------+---------+
         |                 |
+--------+-----------------+---------+
|        |                 |         |
|                           |
|                                    |
|               内核                 |
+------------------------------------+


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


0 0
原创粉丝点击