zoukankan      html  css  js  c++  java
  • Socke基础

    网络协议

    OSI七层网络模型 TCP/IP四层模型 对应网络协议
    应用层(Application) 应用层 HTTP、TFTP、FTP、NFS、WAIS
    表示层(Presentation) Telnet、SNMP、Gopher
    会话层(Session) SMTP、DNS
    传输层(Transport) 传输层 TCP、UDP
    网络层(Network) 网际层 IP、ICMP、ARP、RARP、AKP、UUCP
    数据链路层(Data Link) 网络接口层 FDDI、Ethernet、ARPANET、PDN、SLIP、PPP
    物理层(Physical) IEEE 802.1~IEEE 802.11

    TCP通信过程

    TCP三次握手建立连接过程

    1. 客户端先向服务端发送SYN包(Socket状态从CLOSED变为SYN-SEND)。
    2. 服务端收到SYN包后(Socket状态从LISTEN变为SYN-RECV),向客户端发送针对此SYN包的SYN/ACK包,以确认收到这个SYN包。
    3. 客户端收到此SYN/ACK包后(Socket状态从SYN-SEND变为ESTABLISED),再向服务端发送针对此SYN/ACK包的ACK包。
    4. 服务端收到此ACK包后(Socket从SYN-RECV变为ESTABLISED),连接成功。

    全双工异步通信

    TCP和UDP协议都是全双工的通信协议,通信双方都可以主动向对方发送数据并接受响应。

    通信双方在程序设计上要支持数据的“并行”发送和接受。在全双工通信时,为了达到通信效果,我们需要将数据的传输与数据的加工处理分开,分别由不同的线程处理。这种模式被称为全双工异步通信。

    连接断开的四次握手过程

    1. 客户端向服务器发送FIN数据包,表示想要断开连接。Socket状态从ESTABLISED变为FIN_WAIT_1。
    2. 服务器收到此FIN数据包后,向客户端发送ACK包,表示断开中(检查是否可以断开连接)。Socket状态ESTABLISED变为CLOSE_WAIT。
    3. 客户端接收到ACK包,Socket状态从FIN_WAIT_1变为FIN_WAIT_2状态,等待服务器发送确认断开的数据包。
    4. 服务器在准备完毕后向客户端发送FIN包,确认可以断开连接。其Socket状态从CLOSE_WAIT变为LAST_ACK,等待客户端确认。
    5. 客户端收到服务其的FIN包后,再向服务器发送ACK包,确认可以断开连接,Socket状态从FIN_WAIT_2变为TIME_WAIT。
    6. 服务器收到客户端ACK包后,断开连接,关闭套接字(CLOSED状态)。
    7. 客户端等待一段时间,才真正关闭连接,让Socket状态从TIME_WAIT变成CLOSED。

    第五步的时候,客户端向服务端发送的ACK包有可能因为网络问题导致丢失,从而导致服务端重新发送对应的FIN包。入欧客户端发送ACK包后完全关闭了Socket,那么无论服务端发送多少次FIN包,都收不到客户端的ACK包了,所以客户端要进入TIME_WAIT状态等待一段时间,确认服务器收到ACK包,才进入CLOSED状态。

    通信方式

    长连接与短连接

    每次传输数据之前都要建立新连接,并传输之后关闭连接,这种方式被称为短连接。(HTTP 1.x就是基于TCP短连接的超文本传输协议)

    在客户端和服务端之间建立一个长期的连接,并在其上进行多次通信,直到双方不再需要通信,或者其中一方退出时候才断开连接,这种方式被成为长连接。

    线程模型

    方案1 

    客户端的每个线程都各自创建一个Socket可连接来连接服务端。服务端在接收到新的连接请求后,为每一个连接都创建一个线程来读取和处理数据,并返回结果。

    注意:1.0.0表示发出去的数据,1.0.1表示处理结果数据

     这种模型结构简单,编码容易,不需要对数据进行封包等处理;缺点是并发能力差,效率低。

    方案2

    双方建立一个连接,客户端的多个线程通过独占锁的机制轮流使用Socket。具体步骤

    1. 获取锁
    2. 发送数据
    3. 接收数据
    4. 释放锁

     

     注意:L表示独占锁

    这一个模式需要对数据进行封包,已确定每个数据的边界。其适用于客户端线程不是很多,但是调用频繁。且每个调用耗时很短的场景。

    方案3

    双方只建立一个连接,客户端多个线程通过竞争锁来轮流通过Socket发送数据,并在发送玩数据后阻塞自己,等待唤醒。再用一个专门的线程从Socket中读取结果数据,之后唤醒阻塞的线程,将结果数据传递给他们。

     注意:R代表专门的数据读取线程,B表示线程在获取了锁L并完成数据发送后将自己转为阻塞状态。

    需要注意的是由于服务端的数据处理是多线程并行的,因此么个请求的处理时长不一,无法按数据输入数据返回结果。

    这种模型也需要对数据进行封包,以确定数据边界。由于需要多线程竞争同一个锁,因此,线程数越多性能越差,但是优于前两个方案。

    方案4

    基于方案3,抗客户端的写锁L换成一个数据队列Q,用一个专门的写线程W从队列Q获取数据并发送,减少了竞争锁。

     方案5

    基于方案4,我们再进一步,在服务端也采用发送数据队列和专门的发送线程。

      

  • 相关阅读:
    hdp (ambari) 集成hue
    Hive的metastore
    windows 常用cmd命令
    HDFS datanode心跳与运维中的实际案例
    scala drools and map
    hadoop nn 运维一例
    Eclipse 多行注释选择
    JSP SERVLET 基础知识
    记录一次代码错误,elastic search的INDEX需要使用小写字母
    HIVE大数据出现倾斜怎么办
  • 原文地址:https://www.cnblogs.com/wangb0402/p/12674065.html
Copyright © 2011-2022 走看看