C++中的网络协议和网络框架TCP和HTTP

发布于:2024-07-01 ⋅ 阅读:(15) ⋅ 点赞:(0)

一.OSI七层网络模型

即开放式系统互连。 一般都叫OSI参考模型,是ISO组织在1985年研究的网络互连模型。该体系结构标准定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层),即OSI开放系统互连参考模型。
应用层:HTML class,HTTP APIserver
表示层:CSS,GIF,XML,JSON
会话层:FTP,HTTP,HTTPS,SMTP,Telnet
传输层:TCP,UDP
网络层:IPV4,IPV6,ICMP
数据链路层:IEEE802.2,MAC,ATM
物理层:RS-232

二.TCP 传输协议

TCP 协议:TCP是一个面向连接的,安全的,流式传输协议,这个协议是一个传输层协议。
面向连接:是一个双向连接,通过三次握手完成,断开连接需要通过四次挥手完成。
安全:tcp通信过程中,会对发送的每一数据包都会进行校验, 如果发现数据丢失, 会自动重传
流式传输:发送端和接收端处理数据的速度,数据的量都可以不一致

1.三次握手

第一次握手:客户端向服务端发送连接请求包,标志位SYN(同步序号)置为1,顺序号码为X=0。
第二次握手:服务端收到客户端发过来报文,由SYN=1知道客户端要求建立联机,则为这次连接分配资源。并向客户端发送一个SYN和ACK都置为1的TCP报文,设置初始顺序号码Y=0,将确认序号(ack)设置为上一次客户端发送过来的顺序号(Seq)加1,即X+1 = 0+1=1。
第三次握手:客户端收到服务端发来的包后检查确认号码(ack)是否正确,即第一次发送的Seq加1(X+1=1)。以及标志位ACK是否为1。若正确,服务端再次发送确认包,ACK标志位为1,SYN标志位为0。确认号码(ack)=Y+1=0+1=1,发送顺序号码(Seq)为X+1=1。Server收到后确认号码值与ACK=1则连接建立成功,可以传送数据了。

2.四次挥手

为什么关闭的时候却是四次挥手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
第一次挥手:客户端给服务端发送FIN报文,用来关闭客户端到服务端的数据传送。将标志位FIN和ACK置为1,顺序号码为X=1,确认号码为Z=1。意思是说”我Client端没有数据要发给你了,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK过来。”
第二次挥手:服务端收到FIN后,发回一个ACK(标志位ACK=1),确认号码为收到的顺序号码加1,即X=X+1=2。顺序号码为收到的确认号码=Z。意思是说“你的FIN请求我收到了,但是我还没准备好,请继续你等我的消息" 这个时候客户端就进入FIN_WAIT状态,继续等待服务端的FIN报文。
第三次挥手:当服务端确定数据已发送完成,则向客户端发送FIN报文,关闭与客户端的连接。标志位FIN和ACK置为1,顺序号码为Y=1,确认号码为X=2。意思是告诉Client端“好了,我这边数据发完了,准备好关闭连接了。”
第四次挥手:客户端收到服务器发送的FIN之后,发回ACK确认(标志位ACK=1),确认号码为收到的顺序号码加1,即Y+1=2。顺序号码为收到的确认号码X=2。意思是“我Client端知道可以关闭连接了,但是我还是不相信网络,怕 Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。“(在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。)

3.socket编程
(1).主机字节序:

大端:数据的高位字节存储到内存的低地址位
小端:数据的高位字节存储到内存的高地址位
套接字通信过程中操作的数据都是大端存储的,包括:接收/发送的数据、IP地址、端口
PC机上数据的存储默认使用的是小端
主机字节序到网络字节序的转换函数:htons、htonl;从网络字节序到主机字节序的转换函数:ntohs、ntohl

(2).socket函数:

创建套接字socket,返回文件描述符,这个文件描述符来操作内存,实现网络通信
调用绑定函数bind,将文件描述符和本地的IP与端口进行绑定
调用监听listen给监听的套接字设置监听
调用accept阻塞并等待接受客户端的连接请求, 建立新的连接, 会得到一个新的文件描述符(通信的)
连接成功后,通过调用read和recv来接收数据,如果连接没有断开,接收数据的函数会阻塞等待数据到达,数据到达后函数解除阻塞,开始接收数据,当发送端断开连接,接收端无法接收到任何数据,但是这时候就不会阻塞了,函数直接返回0
通过调用write和send发送数据
通过调用close来关闭套接字

三.HTTP协议

1.HTTP请求头

Accept接收的介质类型
Accept-Charset接受的字符集

2.MFC中Http开发

CInternetSession,创建并初始化一个或多个同时的Internet 会话
CHttpConnection,包含一个构造函数和一个成员函数OpenRequest,使用HTTP协议来管理与服务器的连接
CHttpFile,提供请求和读取 HTTP 服务器上数据和文件的功能;

3.Qt中Http开发

使用QNetworkReply,QNetworkRequest,QNetworkAccessManager
封装成常用的同步和异步的Get请求,Post字串方式请求,Post键值对方式请求等

4.curl开源库Http开发

libcurl是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet 及TFTP这些协议,同时支持使用SSL证书的安全文件传输:HTTP POST, HTTP PUT, FTP 上传, 基于HTTP形式的上传、代理、Cookies、用户加密码的认证等多种应用场景。另外,libcurl是一个高移植性的库,能在绝大多数系统上运行,包括Windows,Linux ,Mac OS,Solaris, NetBSD, FreeBSD, OpenBSD, HPUX AIX, Tru64, UnixWare, HURD, Amiga, BeOs, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS等
libcurl提供了两种接口,分别是easy interface和multi interface。easy interface以同步的方式进行数据传输,执行curl函数时会一直阻塞到数据传输完毕后返回,且一次操作只能发送一次请求,如果要同时发送多个请求,必须使用多线程。 而multi interface以一种简单的、非阻塞、异步的方式进行传输,它允许在一个线程中,同时提交多个相同类型的请求。 在使用multi interface之前,应该先掌握easy interface的基本使用。因为multi interface是建立在easy interface基础之上的,它只是简单的将多个easy handler添加到一个multi stack,而后同时传输而已


网站公告

今日签到

点亮在社区的每一天
去签到