Socket学习

核能气质少年 提交于 2019-12-01 15:53:19
                     https://juejin.im/post/5a069b6d51882509e5432656
 

一、TCP/IP协议

(一)、简介

    TCP/IP协议即传输控制协议/网间协议,定义了主机如何连入因特网,以及数据在它们之间传输的标准TCP/IP协议指因特网整个TCP/IP的协议族,而不是特指某个单独的协议
    TCP/IP协议包括四个抽象层:
  • 应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等
  • 传输层:TCP,UDP
  • 网络层:IP,ICMP,OSPF,EIGRP,IGMP
  • 数据链路层:SLIP,CSLIP,PPP,MTU
    它们之间的关系可用如下图表示:
    
 

(二)、数据包和数据处理流程

    在TCP/IP协议的每个分层中,都会对所发送的数据附加一个首部,这个首部里包含了所在层的相关信息,如要发送的目标地址和协议的相关信息。
    网络中传输的数据包由两部分组成:一部分是协议要用的首部,另一部分是上一层传过来的数据。首部的结构由协议的具体规范详细定义,数据包的首部标明了协议应该如何读取数据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。
    下面以a向b发送邮件为例来看数据的处理流程:
 

(三)、TCP和UDP

1).TCP和UDP区别

    TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP。拿快递举例,TCP就像靠谱的快递公司,每一步都有反馈和监控,但价格也很昂贵UDP就像不靠谱的快递公司,价格低,但能不能收到就要看运气了。两种服务无所谓好坏,TCP可靠但是要消耗大量资源,效率低(适合大块、重要的文件),UDP不保证可靠性,但是效率高(适合对实时性要求较高的通信广播或者一些不太重要的文件)。下面详细的介绍下它们的区别:
    a) TCP是面向连接的、可靠的流协议。TCP通讯类似于打电话,必须双方把电话接通后才能进行通话,任何一方断线都会造成无法进行通话,须再次连接。它充分地实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。TCP 作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费
    b) UDP 是不具有可靠性的数据报协议。UDP协议是一种对等通信的实现,发送方只需要知道接收方的IP和Port,就可以直接向它发送数据,不需要事先连接。每个程序都可以作为服务器,也可作为客户端。细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
 

2).TCP三次握手

    TCP是面向连接进行传输的,因此在通信开始之前就要先做好两端之间的准备工作。而三次握手就是建立连接的方式,客户端和服务端通过三次通信完成连接,在socket编程中,这一过程由客户端执行connect来触发。下面看看过程:
    
  • 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
  • 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
  • 第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
 
3).TCP四次挥手
    四次挥手即终止连接时进行的操作,客户端和服务端通过四次通信断开连接。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
    
  • 中断连接端可以是客户端,也可以是服务器端。
  • 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
  • 第二次挥手:服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。
  • 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
  • 第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。
 
上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况
 

二、Socket

(一)、简介

    下面这张图明确的展示了Socket在网络通信中的位置---位于应用层和传输层之间。
    我们常说的套接字Socket,是一个编程接口(API),是TCP/UDP向开发者提供的用作网络开发的接口,它是对TCP/UDP协议的封装。可以这么理解,有两个进程(一台计算机能有多个进程,比如QQ和微信就可以被看做两个进程),跨计算机,他俩想通讯的话就必须通过网络对接起来,而这就是Socket的作用。这两个进程,需要 有一个进程是被动方,这就是服务器 ;而 另一个则是主动方,这就是客户端 。他们 所在的计算机叫做主机host,在网络上有特定的Ip地址。一台计算机可以有多个进程作为服务器,但是ip地址只有一个,所以要通过不同的 端口port 进行区分。因此,服务器需要绑定在本机的某个端口上,客户端则需要声明自己要连接哪台主机(地址)的哪个进程(端口)。两个进程通过网络(Socket)建立其通讯渠道,然后就能通过recv 和 send 来收发一些信息。所以Socket就是指代联通这种通讯的桥梁(标识)
 

(二)、Socket工作流程

    

    先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
 

(三)、实战Demo

    实战方面推荐这篇专栏,很适合刚接触Socket的童鞋。奉上连接: https://blog.csdn.net/kongxx/article/category/9261021
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!