📄 4.网络编程.txt
字号:
4.网络编程
网络基础
OSI网络参考模型和TCP/IP网络模型
OSI(open systems interconnection开放系统互联)网络模型将网络功能划分为七个层次。他们分别为,物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。
这里只着重的总结一下编程需要涉及的层次,其他的请参考课本。
数据链路层,物理地址(MAC),这是计算机的网络设备的唯一标识,且是不可重复的。这一层的作用是保证相邻两台计算机之间可靠的传输数据。
网络层,IP地址(IPv4协议),四字节(32bit)的网络标识由网络地址和主机地址(节点地址)组成。它标识了本机的主机地址和本机所在网络地址。IP地址是由网络地址和主机地址(节点地址)组成的,他分为五类,A,B,C,D,E。A类地址第一位表示网络地址后三位表示主机地址,B类地址前两位表示网络地址,后两位表示主机地址,C类地址,前三位表示网络,最后一位是主机地址,这种类型也多是我们所用的IP地址。D,E类则是保留地址用于实验室。IP地址就像是一台计算机在网络上的名片一样。
子网掩码,是和本机IP地址按位与运算,获得本机的网络地址。
作用,保证在不同网段内进行网络传输,IP寻址(通过路由器进行寻址和传输)。
传输层,端口(Port),应用程序的标识(网络通信程序),主要是针对这一层在进行编程,运用TCP,UDP协议进行编程。这一层还对传输的数据进行差错检验(面向连接的通讯)流量控制,对数据进行缓冲和使数据传输进行阻塞。用TCP协议进行数据传输能过很好的维护数据的完整性,UDP协议(无连接协议)的传输效率比较高,但数据完整性比较差。
作用,保证数据传输的可靠性,对数据进行流量控制和差错检验。(点到点的传输数据)
应用层,这一层负责与实际的用户程序交互。常用的协议有ftp,http,telnet,pop3,smtp(这些协议在本质上都是TCP或者是UDP协议)。(上层不用关心下层的实现细节)
TCP/IP网络模型,这个模型是参考OSI模型建立起来的,TCP/IP是一个四层协议系统,分别是物理层和链路层,互联网层(对应OSI模型的网络层),运输层和应用层,这些层次的功能大致上和OSI参考模型的相同,TCP/IP模型的应用层是将OSI模型的会话层,表示层,应用层这三层和并未一层,即TCP/IP模型的应用层。(TCP/IP协议在底层是无连接的)。
Socket套接字,用于网络编程。
协议也称协议栈。协议是跨语言跨操作系统的。
IP协议(网际协议)用于不同网段的通信。
同网段间的通过广播进行网络寻址。
IP协议是一个无连接协议。(分组发送数据)
IP地址,上面已经在OSI模型的网络层介绍过IP地址,IP地址,四字节的网络标识有网络地址和主机地址(节点地址)(IPv4协议)它标识这本机的主机地址和本机所在网络地址。IP地址是由网络地址和主机地址(节点地址)组成的,他分为五类,A,B,C,D,E。A类地址第一字节表示网络地址后三字节表示主机地址,B类地址前两字节表示网络地址,后两字节表示主机地址,C类地址,前三字节表示网络地址,最后一字节是主机地址,这种类型也多是我们所用的IP地址。D,E类则是保留地址用于实验室。
网络地址,它唯一的指定了每个网络。在同一网络中的每个计算机的共享相同的网络地址,做为自己IP地址的一部分。
节点地址,是在一个网络中用来唯一表示每台计算机的地址,节点地址也称主机地址。
IP地址的最后一位,不能够是1,或者255,因为这两个数字有特殊意义,1,带表的这个IP地址是网关,255,表示这个IP地址是一个广播地址,也就是它会向同网段(网络地址)的所有计算机发送的数据
192.168.0.20点分十进制表示IP地址。127.0.0.1表示本机,是一个环回地址。
IPv6协议,使用16字节(128bit)的网络标识来标识网络中计算机。他有着更大的IP地址容量,以应对IPv4协议所面临的IP地址枯竭的问题。
TCP协议(传输控制协议)
TCP协议提供了流式接口(控制台和文件)
TCP的连接的建立要通过三个报文段完成的,也称为“三次握手”。
1. 请求端(客户端)发送一个报文段指明客户打算连接的服务器和端口号。(第一次握手)
2. 服务器发回包含服务器初始序号的报文段作应答。(第二次握手)
3. 客户必须将确认序号的报文段发回给服务器。(第三次握手)
连接建立完成。
断开连接
断开连接需要通过四个报文段,四次握手。
1. 请求端(客户端)发送一个报文段指明打算断开连接。(第一次握手)
2. 服务器端发回报文段作应答。(第二次握手)
3. 服务器端等待后发出关闭连接报文段(第三次握手)
4. 客户端发回报文段作应答(第四次握手)
双方连接断开
TCP连接相当于打电话,而UDP就像是寄信。
服务器端
1,申请一个socket()。
2,绑定bind()把socket和IP地址,端口。
3,监听listen()。
4,等待accpet()。
5,接收请求,建立连接。
6,开始数据传输。
7,关闭连接close()。
客户端
1,申请一个socket()。
2,开始连接,输入要连接的服务器的IP地址和端口号connect()。
3,连接建立,开始数据传输。
4,断开连接close()。
Socket编程
1,通用套接字接口地址结构
#include<sys/socket.h>
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_familt;//地址家族,IPv4 or IPv6
char sa_data[14];
}
一般不是用以上结构,而是使用下面的结构。
#include<netinet/in.h>
struct in_addr{
in_addr_t saddr;//32bit的ip地址。
}
sturct sockaddr_in{
uint8_t sin_len;
sa_family sin_family;//地址家族,IPv4 (AF_INET)or IPv6(AF_INET6)。
in_port sin_port;//其实就short int型的变量,用于表示端口号
sturct in_addr sin_addr;//ip地址结构
char sin_zero[8];//用于占位
}
关于ip地址的转换
uint32_t htonl(uint32_t hostlong)<netinet/in.h><sys/types.h><inttypes.h>
uint16_t htons(uint16_t hostshort)<netinet/in.h><sys/types.h><inttypes.h>
这是将主机字节序转换成网络字节序。他的参数就是主机字节序,返回值就是网络字节序。
uint32_t ntohl(uint32_t netlong)<netinet/in.h><sys/types.h><inttypes.h>
uint16_t ntohs(uint16_t netshort)<netinet/in.h><sys/types.h><inttypes.h>
这是将网络字节序转换成主机字节序。他的参数就是网络字节序,返回值就是主机字节序。
把地址转换成char*(字符串)就可以看到每个数据在计算机中的真实地址。
int inet_pton(int family,const char* strptr void* addrptr)<sys/socket.h><arpa/inet.h>点分十进制IP地址,转成整形
family,地址家族。(AF_INFT<IPv4>)
strptr,点分十进制地址,
addrptr,可以用这个空间来保存整形ip。
const char* inet_ntop(int family,const void* addrptr,char* strptr,size_t len)<sys/socket.h><arpa/inet.h>
family,地址家族。(AF_INFT<IPv4>)
addrptr,整形ip地址
strptr,是用于存放转换好的IP地址的空间,len,是这块空间的大小。
int socket(int family,int type,int protocol)用于创建套接字
family地址家族(AF_INET<IPv4>)
type SOCK_STREAM(TCP),SOCK_DGRAM(UDP)
protocol这个参数要置成0。
他的返回值是就是套接字,如果返回值为负那就是创建失败了。
其实Socket本身就是一个特殊的文件。
int bind(int sockfd,const struct sockaddr* myaddr,socklen_t addrlen)用于绑定套接字
sockfd,就是套接字的文件描述符,
myaddr,其实传入的是sockaddr_in的结构,在强转成sockaddr结构。
addrlen ,是地址结构的大小。
注意:在给IP地址结构成员赋值时。用INADDR_ANY,这是一个特殊的宏,他表示的是任意的IP地址,即0.0.0.0这样一个地址不需要转换,但依习惯在使用时还是建议进行转换。在地址结构的port给定时要注意可用的基本上是10000以上的值。
int listen(int sockfd,int backlog)用于把主动套接字转换成被动套接字,也就是把它变成中转站,把数据发送给其他的套接字。
sockfd,套接字的文件描述符。
backlog,最大连接数,最大5~10个
int accept(int sockfd,struct sockaddr* cliaddr,socklen_t addlen)用于等待客户端连接。
sockfd,套接字。
cliaddr,用来存放对方的协议地址信息。
addlen,返回地址结构的长度。
它会返回一个新的套接字。
int connect(int sockfd,const sturct sockaddr* servaddr, socklen_t addrlen)在客户端使用的函数,用来和服务器进行连接。
sockfd,这里的套接字是主动地套接字,可以收发数据。
sockaddr,这是要连接的服务器的ip地址和端口号,这里传入的是sockaddr_in的结构,在强转成sockaddr结构。
addlen,是这个地址结构的长度。
注意:在使用以上函数时需要连接两个库文件,在编译时要加 -lnsl -lsocket
服务器端,这个程序用于接受客户端的连接请求,接收客户端发出的数据或向客户端发出的数据。
写服务器端
1,申请一个socket()。
2,绑定bind()把socket和IP地址,端口。
3,监听listen()。
4,等待accpet()。
5,接收请求,建立连接。
6,开始数据传输。
7,关闭连接close()。
网络编程的客户端,客户端程序的socket不需要绑定(也可以绑定地址和端口),客户端要指明要连接的
服务器的地址和端口。
写客户端
1,创建socket。
2,创建连接connet()。
3,关闭连接和socket。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -