要写出基于UDP的回显服务器我们要先了解一些预备知识如:
(IP地址有两个版本,IPV4与IPV6在这里我们默认IPV4)
IP地址是什么呢?
IP地址是在IP协议中, 来标识 络中不同主机的地址;
对于IPv4来说, IP地址是 个4字节, 32位的整数;
我们通常也使 "点分 进制" 的字符串表 IP地址, 例如 192.168.0.1 ; 点分割的每 个数字表 个字节, 范围是 0 - 255;
理解源IP地址和 目的IP地址
唐僧例 1;从东土大唐而来去往西天取经而去,在这个例子中东土大唐就是源IP,西天取经就是目的IP
认识端口 号
端 口号(port)是传输层协议的内容.
端 口号是 个2字节16位的整数;
端 口号 来标识一 个进程, 告诉操作系统, 当前的这个数据要交给哪 个进程来处理;
IP地址 + 端口 号能够标识 络上的某 台主机的某 个进程;一 个端 号只能被 一个进程占用 .
注意;一个进程可以绑定多个端口号;但一个端口号不可以绑定多个进程。
理解源端口号与目的端口号
传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端 口号和 目的端口 号. 就是在描述 "数据是谁发的, 要发给谁”;
以上我们要先了解一些预备知识,接下来我会带着大家继续探索网络编程之基于UDP的回显服务器,进一步的揭开网络编程的一角
这里为了我们后面的学习我想为大家介绍几个函数
1.有关网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?
发送主机通常将发送缓冲区中的数据按内存地址从低到 高的顺序发出;接收主机把从 网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高 的顺序保存;因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高 地址.TCP/IP协议规定, 网络数据流应采 大端字节序,即低地址 高字节.
所以不管这台主机是 小端机还是大 端机, 都会按照这个TCP/IP规定的 网络字节序来发送/接收数据;如果当前发送主机是小 端, 就需要先将数据转成 大端; 否则就忽略, 直接发送即可;
为使 为了使网络程序具有可移植性,使同样的C代码在大端和小 端计算机上编译后都能正常运 行,可以调 用以下库函数做网 络字节序和主机字节序的转换。
这样就解决了字节序不统一的问题
另外
这些函数名很好记,h表 host(主机),n表 network(网络),l表 32位 整数,s表 16位短整数。例如htonl表 将32位的整数从主机字节序转换为 网络字节序,例如将IP地址转换后准备发送。如果主机是小端字节序,这些函数将参数做相应的 大端转换然后返回;如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。
2.socket编程接口socket 常用API
这是UDP协议常用的API。(其他的接口以后向大家介绍)
3.
sockaddr结构
socket API是一 层抽象的网络编程接口 ,适 于各种底层网络协议,如IPv4、IPv6.然而, 各种网络协议的地址格式各不相同。有以下两种较为常用;
如图
IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址 sockaddr_in结构体表 ,包括16位地址类型, 16位端口号和32位IP地址.
IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
注意socket API可以都 struct sockaddr *类型表 , 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;
sockaddr 结构
sockaddr_in 结构
虽然socket api的接 是sockaddr, 但是我们真正在基于IPv4编程时, 使用的数据结构是sockaddr_in; 这个结构主要有三部分信息: 地址类型, 端口号, IP地址.
4.
地址转换函数
本节只介绍基于IPv4的socket 络编程,sockaddr_in中的成员struct in_addr sin_addr表 32位 的IP 地址但是我们通常 点分 进制的字符串表 IP 地址,以下函数可以在字符串表 和in_addr表 之间转换;
字符串转in_addr的函数:
in_addr转字符串的函数:
其中inet_pton和inet_ntop不仅可以转换IPv4的in_addr,还可以转换IPv6的in6_addr,因此函数接 是void*addrptr,并线程安全,故建议大家使用。(在APUE中, 明确提出inet_ntoa不是线程安全的函数;)
好吧,我也没有想到光接口就讲了这么多。
大家看完了吗,打开链接,我们要正式码代码了哦https://blog.youkuaiyun.com/a15929748502/article/details/80406604