Loading

【C++】socket编程(一):socket是什么&tcp/ip初探

-----初更----2018年1月25日(转载请注明出处)----

前言:

最近想学习一下socket网络编程,在连续学习了三天后,做一个小总结,希望能够给自己以及初学socket的一些帮助。本篇文章涉及理论知识较多,需要充分理解,并且本篇在面试中也是基础内容,几乎必考,如果有不懂得需要百度一下,搞懂。PS:如果有不对的地方或者想进一步探讨的地方希望各位大佬及时与我联系[elve960520@163.com]

#0x01    网络结构

首先要提出的就是大名鼎鼎的七层网络结构(物数网传会表应),如图(来源:网络图片)

 --------OSI七层模型------------------------TCP/IP四层模型-------

这就是网络结构,可以看到传说中的TCP/UDP与传输层是相对应的,也就是说TCP/UDP是在传输层的一种协议,下面会讲TCP/UDP区别。而ip则是对应网络层的,ip就不用多说,包括ipv4和ipv6,本系列教程讲的是ipv4,(貌似ipv6并不常见)。http协议则是在应用层的一种协议,是对TCP/IP的封装,我们写的web应用就是用的http协议,而socket是一种套接字,不存在于哪一层,网上的解释是在传输层和应用层之间的一种接口,详情见这篇文章

#0x02    http协议

http 为短连接:客户端发送请求都需要服务器端回送响应.请求结束后,主动释放链接,因此为短连接。通常的做法是,不需要任何数据,也要保持每隔一段时间向服务器发送"保持连接"的请求。这样可以保证客户端在服务器端是"上线"状态。

HTTP连接使用的是"请求-响应"方式,不仅在请求时建立连接,而且客户端向服务器端请求后,服务器才返回数据。

#0x03    TCP三次握手

TCP三次握手(同时也是socket用TCP建立连接过程):

 

1) 当客户端发起连接请求后,TCP协议会组建一个数据包,并设置 SYN 标志位,表示该数据包是用来建立同步连接的。同时生成一个随机数字 1000,填充“序号(Seq)”字段,表示该数据包的序号。完成这些工作,开始向服务器端发送数据包,客户端就进入了[SYN-SEND]状态。

2) 服务器端收到数据包,检测到已经设置了 SYN 标志位,就知道这是客户端发来的建立连接的“请求包”。服务器端也会组建一个数据包,并设置 SYN 和 ACK 标志位,SYN 表示该数据包用来建立连接,ACK 用来确认收到了刚才客户端发送的数据包。
服务器生成一个随机数 2000,填充“序号(Seq)”字段。2000 和客户端数据包没有关系。
服务器将客户端数据包序号(1000)加1,得到1001,并用这个数字填充“确认号(Ack)”字段。
服务器将数据包发出,进入[SYN-RECV]状态。

3) 客户端收到数据包,检测到已经设置了 SYN 和 ACK 标志位,就知道这是服务器发来的“确认包”。客户端会检测“确认号(Ack)”字段,看它的值是否为 1000+1,如果是就说明连接建立成功。
接下来,客户端会继续组建数据包,并设置 ACK 标志位,表示客户端正确接收了服务器发来的“确认包”。同时,将刚才服务器发来的数据包序号(2000)加1,得到 2001,并用这个数字来填充“确认号(Ack)”字段。
客户端将数据包发出,进入[ESTABLISED]状态,表示连接已经成功建立。

4) 服务器端收到数据包,检测到已经设置了 ACK 标志位,就知道这是客户端发来的“确认包”。服务器会检测“确认号(Ack)”字段,看它的值是否为 2000+1,如果是就说明连接建立成功,服务器进入[ESTABLISED]状态。
至此,客户端和服务器都进入了[ESTABLISED]状态,连接建立成功,接下来就可以收发数据了。

#0x04    TCP四次断开

TCP四次断开(同时也是socket断开TCP连接过程):

 1) 客户端发起断开连接请求后,向服务器发送 FIN 数据包,进入[FIN_WAIT_1]状态。FIN 是 Finish 的缩写,表示完成任务需要断开连接。

2) 服务器收到数据包后,检测到设置了 FIN 标志位,知道要断开连接,于是向客户端发送“确认包”,进入[CLOSE_WAIT]状态。
注意:服务器收到请求后并不是立即断开连接,而是先向客户端发送“确认包”,告诉它我知道了,我需要准备一下才能断开连接。

3) 客户端收到“确认包”后进入[FIN_WAIT_2]状态,等待服务器准备完毕后再次发送数据包。

4) 等待片刻后,服务器准备完毕,可以断开连接,于是再主动向客户端发送 FIN 包,告诉它我准备好了,断开连接吧。然后进入[LAST_ACK]状态。

5) 客户端收到服务器的 FIN 包后,再向服务器发送 ACK 包,告诉它你断开连接吧。然后进入[TIME_WAIT]状态。

6) 服务器收到客户端的 ACK 包后,就断开连接,关闭套接字,进入[CLOSED]状态。

#0x05    TCP/UDP和数据传输方式

计算机之间有很多数据传输方式,各有优缺点,常用的有两种:SOCK_STREAM 和 SOCK_DGRAM。

1) SOCK_STREAM 表示面向连接的数据传输方式。数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送,但效率相对较慢。常见的 http 协议就使用 SOCK_STREAM 传输数据,因为要确保数据的正确性,否则网页不能正常解析。

2) SOCK_DGRAM 表示无连接的数据传输方式。计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。因为 SOCK_DGRAM 所做的校验工作少,所以效率比 SOCK_STREAM 高。
QQ 视频聊天和语音聊天就使用 SOCK_DGRAM 传输数据,因为首先要保证通信的效率,尽量减小延迟,而数据的正确性是次要的,即使丢失很小的一部分数据,视频和音频也可以正常解析,最多出现噪点或杂音,不会对通信质量有实质的影响。

那么,TCP和UDP到底是做什么的呢?

其实,TCP是面向链接的,也就是前面提到的SOCK_STREAM的传输方式,虽然说网络的不安全不稳定特性决定了多少次握手都不能保证连接的可靠性,但TCP的三次握手在最低限度上(实际上也很大程度上保证了)保证了连接的可靠性;而UDP不是面向连接的,也就是SOCK_DGRAM的传输方式,UDP传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,当然也不用重发,所以说UDP是无连接的、不可靠的一种数据传输协议。在socket中对TCP和UDP都有比较良好的支持。

#0x06    socket是什么

以上数据网络的基础,一定要深刻理解,下面简单介绍一下socket,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。学习 socket,也就是学习计算机之间如何通信,并编写出实用的程序。接下来的教程将会详细解释这句话,先大概了解一下socket是怎么建立的,现在只要有个概念就好,慢慢就会理解了。

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

参考:

【1】http://c.biancheng.net/cpp/html/3029.html

【2】http://blog.csdn.net/Pk_zsq/article/details/6087367

【3】https://www.cnblogs.com/meier1205/p/5971313.html#undefined

【4】http://www.360doc.com/content/14/0804/15/12928831_399366221.shtml

【5】http://www.cnblogs.com/L-hq815/archive/2012/07/09/2583043.html

posted @ 2018-01-25 15:50  _小孟同学  阅读(436)  评论(0编辑  收藏  举报