要学Internet上的TCP/IP网络编程,必须深刻理解Socket接口。之所以另起一篇文章来讨论Socket,是因为它是网络通信架构的基础,重要性不言而喻。所谓socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。socket的英文原义是“孔”或“插座”。在这里作为通信机制,取后者意思。socket非常类似于电话插座。以一个国家级电话网为例。电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于socket号(JAVA程序的socket ID 由操作系统分配)。任何用户在通话之前,首先要占有一部电话机,相当于申请一个socket;同时要知道对方的号码,相当于对方有一个固定的socket。然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还要拨对方区号,相当于给出网络地址)。对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求),拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。通话结束后,一方挂起电话机相当于关闭socket,撤消连接。

      在电话系统中,一般用户只能感受到本地电话机和对方电话号码的存在,建立通话的过程,话音传输的过程以及整个电话系统的技术细节对他都是透明的,这也与socket机制非常相似。socket利用网间网通信设施实现进程通信,但它对通信设施的细节毫不关心,只要通信设施能提供足够的通信能力,它就满足了。

至此,我们对socket进行了直观的描述。抽象出来,socket实质上提供了进程通信的端点进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。正如打电话之前,双方必须各自拥有一台电话机一样。在网间网内部,每一个socket用一个结构体相关描述:(协议,本地地址,本地端口) 一个完整的socket有一个本地唯一的socket号

最重要的是,socket 是面向客户/服务器模型而设计的,针对客户和服务器程序提供不同的socket 系统调用。客户随机申请一个socket (相当于一个想打电话的人可以在任何一台入网电话上拨号呼叫),系统为之分配一个socket号;服务器拥有全局公认的 socket ,任何客户都可以向它发出连接请求和信息请求(相当于一个被呼叫的电话拥有一个呼叫方知道的电话号码)。

     socket利用客户/服务器模式巧妙地解决了进程之间建立通信连接的问题。服务器socket 半相关为全局所公认非常重要。一般来说,编好程序 > 访问,调用,数据填充,逻辑组织 > socket组件 > 操作系统的通信API > 到达网线出口。这样就可以实现与外部的连接。

在网络上查找socket相关资料的时候,经常会把socket和电话插座拿来对比,不仅仅是因为socket的英文原义是“插座”,更重要的是,电话机发送信号和对方从电话机接收信号的过程,相当于socket发送和接收数据的过程。对于通话双方来说,通信设施的细节不重要,重要的是两端都有电话机,也就是都支持socket这样的连接方式。

webSocket机制

websocket是一个基于TCP连接的全双工通信方式,服务端和客户端可以相互推送数据。

我们可以看看websocket是如何保持客户端和服务端通信的。

这里需要注意一点,websocket在连接的时候有一个握手阶段,但是这和TCP的三次握手又是不一样的。TCP的三次握手是为了保证连接可靠,当TCP三次握手成功的时候,websocket的握手阶段才真正开始。TCP三次握手传送的是TCP报文,而websocket的握手传送的是HTTP报文,这个是不太一样的地方。

握手开始的时候,我们需要现发送一个HTTP 1.1的请求头部:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

服务端返回的成功握手请求头部如下:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

Upgrade:WebSocket表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。

一旦连接成功后,就可以在全双工的模式下在客户端和服务端之间来回传送WebSocket消息。这就意味着,在同一时间、任何方向,都可以双向发送基于文本的消息。每个消息已0×00字节开头,以0xff结尾(这样就可以解决TCP协议中的黏包问题,在TCP协议中,会存在两个缓冲区来存放发送的数据或者接收的数据,如果没有明显的分隔符,服务端无法正确识别命令),中间数据的编码是UTF-8。

关于如何使用WebSocket也不赘述,主要还是说说WebSocket带来了什么。

WebSocket的优势

传输速度收到的影响很多,我们可以从多个角度对HTTP和WebSocket进行比较。

从纯粹的字节数角度考虑

HTTP:每一次数据传输都需要有一个HTTP头部,头部的大小不一,可能只有几百B,也可能有几千B。

WebSocket只有在进行连接的时候需要发送一个HTTP请求,之后就再也不需要发送纷繁的HTTP头部信息,光从字节数上就减少了很多。而在关闭WebSocket的过程中,也不需要像建立握手的时候那么繁杂,只需要传送一个特定的字节码0×8的关闭帧就行,服务端收到之后,需要响应一个关闭帧到客户端。

从请求数的角度考虑

正常情况下,如果我们要请求多个数据,就多发多次HTTP请求,整个过程包括建立连接,关闭连接,特别是建立连接的时间在整个传输时间中还占据了比较大的比重。HTTP长连接的劣势也在上面有描述过。

WebSocket可以一直保持连接,通过Socket通道传输数据,节省掉了建立连接需要耗费的时间。

从服务器并发数的角度考虑

服务端要同时维持大量连接处于打开状态,就需要能以低性能开销接收高并发数据的架构。此类架构通常是围绕线程或所谓的非阻塞 IO 而设计的。这就与传统服务器围绕 HTTP 请求/响应循环的设计不同。这个时候,我们就会想到nodejs,使用事件机制和异步IO对请求进行处理,提高了服务器的并发能力,并且减少了线程切换带来的开销。

Java曾引入一个新的I/O API,其被称为非阻塞式的I/O。这一API使用一个选择器来避免每次有新的HTTP连接在服务器端建立时都要绑定一个线程的做法,当有数据到来时,就会有一个事件被接收,接着某个线程就被分配来处理该请求。因此,这种做法被称为每个请求一个线程(thread-per-request)模式。其允许web服务器,比如说WebSphere和Jetty等,使用固定数量的线程来容纳并处理越来越多的用户连接。在相同硬件配置的情况下,在这一模式下运行的web服务器的伸缩性要比运行在每个连接一个线程(thread-per-connection)模型下的好得多。

每个连接一个线程模式通常会有一个更好的响应时间,因为所有的线程都已启动、准备好且是等待中,但在连接的数目过高时,其会停止提供服务。在每个请求一个线程模式中,线程被用来为到达的请求提供服务,连接则是通过一个NIO选择器来处理。响应时间可能会较慢一些,但线程会回收再用,因此该方案在大容量连接方面有着更好的伸缩性。

而WebSocket对于服务端的优势就在于Socket减少了数据传输和处理的成本,使得这些异步的IO机制能够充分地扬长避短。

换句话说,WebSocket带来的并发能力提升,不仅仅因为传输机制本身,服务端一样需要做调整来适应新的机制,这样才能充分发挥WebSocket的优势。

Socket.io

Socket.IO是一个JavaScript端的框架, 提供了一个简单类似WebSocket的API,实现异步接收和发送服务端数据。Socket.io支持WebSocket,Flash Sockets,长轮询,流,持久帧(iframe)和JSONP轮询。具体使用哪个方案取决与浏览器的兼容性,尽可能使用最优方案解决。

  

详解Socket接口相关推荐

  1. 支付接口教程,详解支付宝接口(二)

    支付宝的接口向来集成过程都让人觉得比较舒服,只有APP支付相对复杂,但也只是配置上复杂一些,只要清楚原理相信也不是什么难事.下面是以前介绍双钥加密原理的传送门: 支付接口教程特别篇,公钥与私钥,双钥加 ...

  2. 详解EBS接口开发之采购申请导入

    更多内容可以参考我的博客  详解EBS接口开发之采购订单导入 http://blog.csdn.net/cai_xingyun/article/details/17114697 /*+++++++ ...

  3. 详解EBS接口开发之WIP模块接口

    详解EBS接口开发之WIP模块接口 2014-07-23 22:53:49 caixingyun 阅读数 11780  收藏 更多 分类专栏: 详解EBS接口开发系列 版权声明:本文为博主原创文章,遵 ...

  4. 详解EBS接口开发之供应商导入(转载)

    详解EBS接口开发之供应商导入(转载) https://blog.csdn.net/f_zhangyu/article/details/80254191 (一)供应商常用标准表简介 1.1 常用标准表 ...

  5. 【Linux】详解socket编程接口

    socket编程接口详解 1. socket常见API 2. IPv4协议的地址信息结构:sockaddr_in结构体 2.1 sockaddr结构体 2.2 in_addr结构体 2.3 socka ...

  6. 合宙lua库详解-socket

    文章目录 简介 START 建立连接 发送数据 接收数据 关闭连接 主动关闭 被动关闭 简介 作为通讯的基础,只要你上网就需要用到lua的socket模块,即使使用mqtt,http等其它模块间接也调 ...

  7. linux socket bind 内核详解,Socket与系统调用深度分析(示例代码)

    1. 什么是系统调用 操作系统通过系统调用为运行于其上的进程提供服务.当用户态进程发起一个系统调用, CPU 将切换到 内核态 并开始执行一个 内核函数 . 内核函数负责响应应用程序的要求,例如操作文 ...

  8. android中接口的作用是什么意思,详解Android接口Interface的使用和意义

    本文介绍是Android的一个重要的东西,接口Interface,详解两个方面: (1)Java是继承的,接口Interface是可以多个的,恰恰弥补了这个缺点. (2)回调,接口Interface里 ...

  9. java类与接口思维导图_详解java接口基础知识附思维导图

    接口: 官方的含义是---->java接口是一系列方法的声明,是一些方法特征的集合 疑问: 那为什么不用抽象类呢?把他们共有的方法集合起来放在一个抽象类里面,同样可以调用哇,但是反过来想一想如果 ...

最新文章

  1. 【1】青龙面板入门系列教程之服务器的选择及初始化
  2. Python编程基础:第六节 math包的基础使用Math Functions
  3. 401 Unauthorized
  4. Spring Cloud构建微服务架构-Hystrix监控面板
  5. b+树阶怎么确定_B站公布年度弹幕,这个排名我不太服气
  6. 黄聪:Destoon中循环嵌套Loop和php代码结合调用自增长数字
  7. linux-查看用户id-查看文件目录所有者-查看进程操作者
  8. 您不知道Bash:Bash阵列简介
  9. 实现一个基于Vue的Button小组件
  10. sql日期大于某天_(十五)sql/Linux 小技巧
  11. JBoss企业级应用服务平台群集指南(一)
  12. [DB2]DB2中的数值类型
  13. GoogleNet家族
  14. 大数据Hadoop基本概念介绍
  15. 快速修改Windows系统字体样式
  16. ffmpeg转码参数
  17. 液晶电视测试软件u盘,突破封锁!用U盘给电视安装APP居然这么简单
  18. AutoCAD快速入门(二十九):视口
  19. APM 页面加载耗时校准
  20. 医学病理图片(SVS格式)的格式转换与显示——python实现

热门文章

  1. SHA算法Java实现
  2. 克拉维酸类毕业论文文献包含哪些?
  3. 扯一扯HTTPS单向认证、双向认证、抓包原理、反抓包策略
  4. 【第51天| 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 】
  5. IT综合运维系统-身份对接记录
  6. [基本功]卡方分布、卡方检验、卡方分箱
  7. 怎么用vscode进行单步调试
  8. python函数参数以及顺序
  9. SAP MM inforecord采购信息记录创建 BAPI
  10. 模型训练终止训练方法