草庐IT

四、SOCKET 协议

jysf98746 2024-01-02 原文

SOCKET 协议
Socket 是传输层协议的具体软件实现,它封装了协议底层的复杂实现方法,为开发人员提供了便利的网络连接。Socket 是网络编程的基石,像 Http 的请求,MySQL 数据库的连接等绝大部分的网络连接都是基于 Socket 实现的。

1. 传输层协议
传输层有 TCP/UDP 两种连接方式,所以对应的 Socket 也有两种不同实现方式,掌握 Socket 的前提是了解清楚这两种协议。

1.1 TCP 协议
面向连接,且具备顺序控制和重发机制的可靠传输。他的可靠性是在于传输数据前要先建立连接,确保要传输的对方有响应才进行数据的传输。因此 TCP 有个经典的 3 次握手和 4 次挥手。

3 次握手
握手的目的是为了相互确认通信双方的状态都是正常的,没有问题后才会进行正式的通信:

第一次握手:客户端发送请求连接的消息给服务端,但发出去的消息是否到达并不清楚,要基于第二次握手的反馈;
第二次握手:服务端返回消息说明客户端的消息收到了,此时它也纠结了,我的反馈信息对方有没有收到,所以得依托第三次得握手;
第三次握手:客户端反馈第二次握手的消息收到了。至此,通信双发的发送消息和接受消息能力都得到了检验。
3 次握手的整个过程看着似乎有点过于谨慎,但是互联网的初期网络基础设施是很落后的,丢包的概率非常大的。而且这个过程也只是在通信前期建立连接的时候进行,3 次握手过后就是正常的消息传输了。

4 次挥手
4 次挥手的目的跟 3 次握手目的是一样的,谨慎的确保双方消息状态的准确:

第一次挥手:客户端(服务端也可以主动断开)向服务端说明想要关闭连接;
第二次挥手:服务端首先回复第一次的消息已经收到。但是并不是立马关闭,因为此时服务端可能还有数据在传输中;
第三次挥手:待到数据传输都结束后,服务端向客户端发出消息,告知一切都准备好了,我要断开连接了;
第四次挥手:客户端收到服务端的断开信息后,给予确认。服务端收到确认后正式关闭。客户端自己也发出关闭信息,因为服务端已经关闭了无法确认,等到一段时间后客户端正式关闭。
1.2 UDP 协议
UDP 是一种不可靠的传输机制,但是它的数据报文比 TCP 小,所以相同数据的传输 UDP 所需的带宽更少,传输速度更快。它不要事先建立连接,知道对方的地址后直接数据包就扔过去,也不保证对方有没有收到。

2. 连接方式
我们知道 TCP 数据发送前要建立连接,UDP 不需要,而 Socket 的连接又有如下区分:

2.1 长连接
两个节点建立连接并保持不断开的状态;
两边双向自由的进行数据传输;
直到数据全部交互结束才断开。
2.2 短连接
节点 A 向节点 B 建立连接;
A 发送数据给 B;
一条数据发送完立马断开。
2.3 适用场景
连接的建立需要开销,频繁的重建连接容易造成资源浪费,长连接适合客户端和服务端都比较明确且传输数据比较大的情况;
每台服务器的连接数都是有限制的,如果太多的长连接阻塞会影响到新连接的建立。Http 是一种短连接的方式,这样有利于他处理高并发的请求。有一种 slowHttp 的攻击,就是利用 Http 协议的特点,故意制造了一个很长的报文,然后每次发送很少量的数据,使请求一直占用最终耗尽服务器的连接。所以 Http 虽然是短连接,但是一般是等到数据传输完成才断开的,我们应该根据具体业务设置 Http 请求的超时时间。
3. socket 编程
下面的代码实现了一个 Socket 的服务端服务和一个客户端,服务端在 6000 端口上面监听连接,收到客户端的连接后向客户端发出 hello 问候语,客户端打印出服务端发送过来的消息。

3.1 服务端

public class Server {
    public static void main(String[] args) {
        // 创建一个serverSocket监听本地的6000端口
        try(ServerSocket server = new ServerSocket (6000)) {
            // 当有客户端连接上就建立一个socket通道
            Socket socket = server.accept();
            OutputStream outputStream = socket.getOutputStream();
            // 有客户端连接上来就主动发送问候语
            outputStream.write("hello".getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.2 客户端

public class Client {
    public static void main(String[] args) {
        // 根据{IP}+{port}与服务器建立连接
        try( Socket socket=new Socket("127.0.0.1",6000)){
            BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 打印服务端发送的信息
            System.out.println("Client:"+bufferedReader.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. websocket
Websocket 是一种升级版的 Http 服务,传统的 Http 服务都是客户端发起,服务端响应,而 Websocket 支持服务端向客户端主动推送消息,增强了浏览器的交互场景。Websocket 也是应用层协议,跟 Http 一样具体的实现都要基于 Socket,除此之外并没有什么特殊。

5. 小结
几乎所有的软件都需要通信,而几乎所有的通信都是基于 Socket 实现的,Socket 从软件的层面屏蔽了传输层的细节,开发人员可以很方便的使用。Socket 起源于 Unix,而 Unix/Linux 基本哲学之一就是“一切皆文件”,使用的时候就打开,不用就关闭。

有关四、SOCKET 协议的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  3. ruby - HTTP POST 上的 SSL 错误(未知协议(protocol)) - 2

    尝试通过SSL连接到ImgurAPI时出现错误。这是代码和错误:API_URI=URI.parse('https://api.imgur.com')API_PUBLIC_KEY='Client-ID--'ENDPOINTS={:image=>'/3/image',:gallery=>'/3/gallery'}#Public:Uploadanimage##args-Theimagepathfortheimagetoupload#defupload(image_path)http=Net::HTTP.new(API_URI.host)http.use_ssl=truehttp.verify

  4. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  5. 网络实验之RIPV2协议(一) - 2

    一、RIPV2协议简介  RIP(RoutingInformationProtocol)路由协议是一种相对古老,在小型以及同介质网络中得到了广泛应用的一种路由协议。RIP采用距离向量算法,是一种距离向量协议。RIP-1是有类别路由协议(ClassfulRoutingProtocol),它只支持以广播方式发布协议报文。RIP-1的协议报文无法携带掩码信息,它只能识别A、B、C类这样的自然网段的路由,因此RIP-1不支持非连续子网(DiscontiguousSubnet)。RIP-2是一种无类别路由协议(ClasslessRoutingProtocol),支持路由标记,在路由策略中可根据路由标记对

  6. 已解决socket.timeout : The read operation timed out - 2

    已解决(pip安装模块超时,利用四种国内镜像源完美解决)WARENTING:Retrying(Retry(total=4,connect=None,read=None,redirect=None,status=None))afterconnectionbrokenby‘ConnectTimeoutError(pip._vendor.urllib3.connection.HTTPSConnectionobjectatOx00001D6OE4F4A940>,‘Connectiontopypi.orgtimedout.(connecttimeout=15)’)’':/simple/pip/socke

  7. ruby - Cucumber 测试无法启动,错误为 "Display socket is taken but lock file is missing.." - 2

    运行cucumber后bundleexeccucumberfeatures/emails.feature:20我遇到了错误Displaysocketistakenbutlockfileismissing-checktheHeadlesstroubleshootingguide(Headless::Exception)/Users/me/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/headless-2.2.0/lib/headless.rb:195:inensure_xvfb_is_running'/Users/me/.rbenv/ver

  8. ruby - Interface Builder 看不到 MacRuby 的 socket - 2

    我正在尝试使用XCode和InterfaceBuilder构建一个基本的helloworld应用程序。但是,在InterfaceBuilder中,我看不到我的socket可以连接起来。我转到对象检查器Pane的连接选项卡,它显示“NewReferencingOutlet”。我想知道我的代码是否有误。在这里classHelloWorldControllerattr_accessor:hello_label,:hello_button,:hellodefawakeFromNib@hello=trueenddefchangeLabel(sender)if@hello@hello_label.

  9. ruby - 协议(protocol)族不支持的地址族 - 2

    我尝试执行此页面中显示的ruby示例:http://tomayko.com/writings/unicorn-is-unix但我得到的只是echo.rb:9:in`bind':Addressfamilynotsupportedbyprotocolfamily-bind(2)(Errno::EAFNOSUPPORT)fromecho.rb:9:in`'有什么想法吗? 最佳答案 我遇到了同样的问题。只需将localhost更改为0.0.0.0:address=Socket.pack_sockaddr_in(4242,'0.0.0.0')

  10. ruby - yarn 未初始化常量 Socket::SOL_TCP - 2

    我在这里尝试使用yarn,遇到了一个可能与ruby​​相关的问题。在执行任何yarn命令,我收到错误.../.rvm/gems/ruby-2.3.0/gems/yarn-0.1.1/lib/yarn/server.rb:14:in':uninitializedconstantSocket::SOL_TCP(NameError)错误堆栈:$yarn.../.rvm/gems/ruby-2.3.0/gems/yarn-0.1.1/lib/yarn/server.rb:14:in':uninitializedconstantSocket::SOL_TCP(NameError)Didyoume

随机推荐