网络编程中重要的几个数据结构和函数

IPv4相关结构:

struct in_addr
{
    in_addr_t          s_addr;  //表示32位的IP地址,32位无符号整型
}

struct sockaddr_in
{
    uint8_t            sin_len;       //表示该结构体的长度,8位无符号整型
    sa_family_t        sin_family;    //表示套接口使用的协议族,8位无符号整型
    in_port_t          sin_port;      //表示套接口使用的端口号,16位无符号整型
    struct in_addr     sin_addr;      //表示IP地址,32位无符号整型
    char               sin_zero[8];   //该成员基本不使用,总是置为0
}
  • sin_len成员是不要求一定存在的,即便这个成员存在,也无需设置它或者检查它。换句话说就是一般情况下,我们用不到这个成员。
  • sin_family,sin_addr,sin_port这三个成员是必须的。并且几乎所有的实现都增加了sin_zero成员。
  • sin_family的类型与sin_len成员有关,如果结构体中定义了成员sin_len,那么sin_family一般就是8位无符号整型。
  • 如果结构体中没有定义成员sin_len,那么sin_family一般就是16位无符号整型,这样一来整个结构体的大小至少是16字节(1+1+2+4+8)。

IPv6相关结构:

struct in6_addr
{
    unit8_t              s6_addr[16]; //表示128位的IP地址,这里采用数组的形式
}

struct sockaddr_in6
{
    uint8_t              sin6_len;         //表示该结构体的长度,8位无符号整型
    sa_family_t          sin6_family;      //表示套接口使用的协议族,8位无符号整型
    in_port_t            sin_port;         //表示套接口使用的端口号,16位无符号整型
    uint32_t             sin_flowinfo;     //低序20位是流标签,高序12位保留
    struct in6_addr      sin6_addr         //表示128位的IP地址
    uint32_t             sin6_scope_id;    //标识对于具备范围的地址而言有意义的范围
}
  • 28个字节

通用套接口地址结构:

struct sockaddr
{
    uint8_t              sa_len;
    sa_family_t          sa_family;
    char                 sa_data[14];        //表示14字节的协议地址

}
  • 当作为参数传递给任一个套接口函数时,套接口地址结构总是通过指针来传递,但通过指针来取得此参数的套接口函数必须处理来自所支持的任何协议族的套接口地址结构。因此通过定义sockaddr来获取不同的套接口地址结构。
  • 大小16个字节

新的通用套接口地址结构:

struct sockaddr_storage
{
    uint8_t              ss_len;             //表示该结构的长度
    sa_family_t          ss_family;          //表示协议族
    char __ss_padding[_SS_PADSIZE];
}
  • 原有的通用数据结构sockaddr只有16个字节,无法兼容ipv6格式,sockaddr_storage足够大,可以容纳任何套接字接口地址
  • sockaddr_storage 能满足最苛刻的对齐要求
  • 想使用sockaddr_storage中,除了ss_len和ss_family外的其他字段,必须强制转换成其他类型(如sockaddr),再获取。

inet_pton和inet_ntop函数

这两个是随ipv6一起出现的新函数,支持ipv4和ipv6,函数名称中p的意思是表达(presentation),n的意思是数值(numeric),表达是ACSII字符串,数值是内存里的二进制值,顾名思义,inet_pton,将字符串转为数值,inet_ntop,将数值转为字符串。

#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrstr); //成功返回1,strptr格式错误返回0,失败返回-1
const char *inet_ntop(int family, const void *addrstr, char *strptr, size_t len); //成功则返回指向结果的指针,失败返回NULL
  • family参数根据协议族的不同,选择AF_INET或AF_INET6
  • inet_pton 将strptr指向的字符串,转为数值,存放在addstr指向的内存中
  • inet_ntop 做相反的运算,len参数是strptr单元的大小,防止溢出。为有助于指定大小,C语言中有做如下定义。
#incldue <arpa/inet.h>
#define INET_ADDRSTRLEN    16
#define INET6_ADDRSTRLEN   46

原文地址:https://www.cnblogs.com/shenlinken/p/9385346.html

时间: 2024-11-13 03:59:30

网络编程中重要的几个数据结构和函数的相关文章

网络编程中的关键问题总结

总结下网络编程中关键的细节问题,包含连接建立.连接断开.消息到达.发送消息等等: 连接建立 包括服务端接受 (accept) 新连接和客户端成功发起 (connect) 连接. accept接受连接的问题在本文最后会聊到,这里谈谈connect的关键点:     使用非阻塞连接建立需要注意:     connect/select返回后,可能没有连接上:需要再次确认是否成功连接: 步骤为: 使用异步connect直接连接一次,因为使用了非阻塞,函数立刻返回: 检查返回值,为0成功连接,否则加入到s

Unix网络编程中的五种I/O模型_转

转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描述符.接受数据缓冲地址.大小传递给内核,但是如果此时 该与该套接口相应的缓冲区没有数据,这个时候就recvfrom就会卡(阻塞)在这里,知道数据到来的时候,再把数据拷贝到应用层,也就是传进来的地址空 间,如果没有数据到来,就会使该函数阻塞在那里,这就叫做阻塞I/O模型,如下图: 2. 非阻塞I/O模

用java网络编程中的TCP方式上传文本文件及出现的小问题

自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文件给服务端,服务端接收数据并显示“上传成功”给客户端. 客户端: 1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.IOException; 4 import java.io.InputStr

linux网络编程中INADDR_ANY的使用

网络编程中常用到bind函数,需要绑定IP地址,这时可以设置INADDR_ANY INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”.“任意地址”. 也就是表示本机的所有IP,因为有些机子不止一块网卡,多网卡的情况下,这个就表示所有网卡ip地址的意思. 比如一台电脑有3块网卡,分别连接三个网络,那么这台电脑就有3个ip地址了,如果某个应用程序需要监听某 个端口,那他要监听哪个网卡地址的端口呢?如果绑定某个具体的ip地址,你只能监听你所设置的ip地

网络编程中的同步与异步

网络编程中有三对关键的词,单线程与多线程.阻塞与非阻塞.同步与异步,同步与异步一直是比较疑惑的地方.以前认为,同步就是阻塞socket,异步就是非阻塞socket,现在发现这样理解很片面的,其实好多地方有同步异步的概念. 数字电路中的同步与异步是针对时钟来说的 同步时序逻辑电路:各触发器有相同的时钟脉冲,时钟脉冲到来时所有触发器状态同时改变异步时序逻辑电路:没有统一的时钟脉冲,所有触发器的状态转换不一定发生在同一时刻,某些触发器的状态转换有可能会延迟. 在通信原理中也有同步与异步的概念 同步传输

浅谈TCP/IP网络编程中socket的行为

我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: . TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) . Socket I/O系统调用(重点如read/write),这是TCP/IP协议在应用层表现出来的行为. . 编写Performant, Scalable的服务器程序.包括多线程.IO Multiplexing.非阻塞.异步等各种技术. 关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illust

网络编程中shut_down和close()函数的区别

在Linux C网络编程中,一共有两种方法来关闭一个已经连接好的网络通信,它们就是close函数和shutdown函数,它们的函数原型分别为: 1 #include<unistd.h> 2 int close(int sockfd) 3 //返回:0--成功, 1--失败 4   5 #include<sys/socket.h> 6 int shutdown(int sockfd, int howto) 7 //返回:0--成功, 1--失败 对一个tcp socket调用clos

socket编程之三:socket网络编程中的常用函数

这节本来打算先给出常用函数介绍,再给两个代码实例,写着写着发现越来越长,决定把代码放在下一节. 本节内容持续更新...... 1 socket()函数 原型: int socket(int domain, int type, int protocol); 描述: 类似打开一个文件,返回一个socket描述符,唯一标识一个socket,后面相应的操作都是这用这个socket描述符. 参数: domain:协议族,常用的协议族有AF_INET.AF_INET6.AF_LOCAL.AF_ROUTE等:

关于网络编程中MTU、TCP、UDP、IP

名词解释: MTU(Maxium Transmission Unit)最大传输单元 TCP (Transmission Control Protocal)传输控制协议 UDP (Usage Datagram Protocal)用户数据报协议 IP (Internet Protocal) 因特网协议 TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层(TCP/IP是一个协议簇,并不是代表TCP协议和IP协议) 以太网(Ethemet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传