Java Socket 的工作机制
转载,请加上原文链接;
目录
socket 对象的创建时间
这里需要一点TCP的知识, TCP状态分析请看 ——> TCP转态转换讲解(可点击)
当客户端想要与服务器通信的时候,客户端就会 准备 创建一个 socket 对象, 注意,是准备创建,并不是立刻就创建出来;因为在正确创建 socket 对象之前,需要先进行三次握手,如果三次握手失败,那么客户端创建 socket 对象就会失败,抛出一个 IOException 异常 ;只有当三次握手成功,客户端处于 ESTABLISHED 状态,才会正确的创建出 socket 对象 ;
在服务器端,服务器会事先就创建一个 ServerSocket 对象, 这个对象一般随着服务器的启动,就会得到创建,这里没有三次握手; ServerSocket 对象里面指定了 监听端口 和 监听地址 ; ServerSocket 对象里面有2个数据列表,一个是 未完成连接数据列表、一个是 已完成连接数据列表 ;
其中 监听端口,就是监听指定端口的请求,比如监听服务器的8080端口,那么只有访问8080端口的请求,我们的这个 ServerSocket 对象才会处理 ,这里面的端口号 需要我们自己写;
而 监听地址,则是因位 一个服务器,可以设置多个 IP 地址 ,我们要是想只对访问其中某一个IP地址的请求进行处理,那么就在 监听地址 里面,写上我们要监听的那个 IP 地址 ;一般情况下,我们写上 通配符 * ,即监听所有IP地址 ;
当客户端向服务器发起请求连接的时候(注意:这个请求连接只是客户端发送一个 SYN ,是 第一次握手),服务器端的 ServerSocket 对象 ,会根据请求,创建一个 套接字数据结构,注意,这时候,服务端的socket对象,并没有完全 创建 (没有完全创建,类似于构造器得到执行,但是还没有返回实例);并且把这个 套接字数据结构 放到 未完成连接数据列表 里面 ; 只有当与客户端完成三次握手以后,服务器也进入 ESTABLISHED 状态,才会返回 socket 对象 ,并将 socket 对象对应的 套接字数据结构 从 未完成连接数据列表 里面转移到 已完成连接数据列表 里面 ;
(其中,在
已完成连接数据列表中的每一个套接字数据结构都代表着一个TCP连接)
结论:当客户端向服务器发起请求的时候(发送 SYN),客户端是未完全创建出 socket 实例的;在服务器端,当服务器接收到客户端的请求的时候(收到 SYN),也是未完全创建出 socket 实例的 ;
只有当两人完成 三次握手 以后,才会完全的创建出 socket 实例 ;
socket 通信可能会造成死锁
分析这个问题之前,我们需要知道 socket 对象里面有三个缓冲区;
SendQ:缓存已经写入到输入流里面,但是接收到还未成功接收的字节;RecvQ:缓存接收到的字节,但是还没有被分配到具体的应用程序 ;Delivered:缓存着从RecvQ中已经被具体程序读取了的字符 ;
这里我们需要知道,当发送的的 SendQ 满了以后,发送端就进入阻塞状态,不可以再发信息,这时候 TCP协议 负责将发送端 SendQ 中的内容转移到 接收端的 RecvQ 中,这样接收端的 SendQ 就又有了空间,可以继续对外发送信息 ;
上面是 TCP控制机制,这样做的目的是,为了协调双方的压力,让双方的压力不要太大;否则,发送端一个劲的写数据,写了几个G的数据,接收端一次性接收几个G的数据,双方的压力都不小 ;
正是由于 TCP控制机制 的存在,才会导致了死锁的发生;(成也萧何败萧何)
我们想一下,当通信双方(A方、B方),都向对方写数据,并且数据量还不小(比 SendQ + RecvQ 两个缓存区大就可以造成死锁了,这两个缓冲区大小也就是几十 KB,具体的忘记了,反正不大)
当 A 把自己的 SendQ 写满了,TCP 发现以后,就把里面的数据转移到 B 的 RecvQ 里面,正常情况下,B 发现自己的 RecvQ 里面有数据,就会去读数据;
但是现在,B也在写数据,我们知道一个线程,同时只能做一件事的; B 把自己的 SendQ 写满了,TCP 发现以后,就把里面的数据转移到 A 的 RecvQ 里面,正常情况下,A 发现自己的 RecvQ 里面有数据,就会去读数据,但是现在 A 也在写数据哦,也就是双方都在写数据,没有人去读数据;
好了,现在只要他们把各自的 SendQ 和 对方的 RecvQ 写满了,就会陷入 阻塞 转态,等待对方读数据,以便继续写数据;但是现在的情况的是,双方都阻塞了;完犊子了,就一直阻塞下去了;
我们回头分析下,这个问题产生的根本原因是啥?两边同时写大量的数据?其实这不是本质原因,本质原因是我们之前学的IO 都是 BIO 即 阻塞IO,我们必须要等待 读\写 操作,完成以后,才可以继续下面的操作;
一旦 读\写 的动作未完成,就会进入阻塞状态,等待它完成,才可以执行下面的代码;
因此,这个问题解决的根源在于:使用 NIO(即非阻塞IO );
Java Socket 的工作机制的更多相关文章
- 2 深入分析 Java IO的工作机制(一)
大部分Web应用系统的瓶颈都是I/O瓶颈 2.1 Java的I/O类库的基本架构 Java的I/O操作类在包java.io下,大概有将近80个类,这些类大概可以分成如下4组. 基于字节操作的I/O接口 ...
- 深入分析Java I/O 工作机制
前言 : I/O 问题是Web 应用中所面临的主要问题之一.而且是任何编程语言都无法回避的问题,是整个人机交互的核心. java 的I/O类操作在java.io 包下,将近80个子类, 大概可以分成 ...
- java I/O工作机制
java I/O 的基本架构: 1:基于字节操作的I/O接口 InputStream OutputStream 2:基于字符操作的I/O接口 Writer 和Reader 3:基于磁盘操作的I/O接口 ...
- Java I/O 工作机制(一) —— Java 的 I/O 类库的基本架构
Java 的 I/O 类库的基本架构 Java 的 I/O 操作类在包 java.io 下,有将近 80 个类. 按数据格式分类: 面向字节(Byte)操作的 I/O 接口:InputStream 和 ...
- Java I/O 工作机制(二) —— Java 的 I/O 的交互方式分析
简介: BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善. ...
- Java Web ClassLoader工作机制
一.ClassLoader的作用: 1.类加载机制:父优先的等级加载机制 2.类加载过程 3.将Class字节码重新解析成JVM统一要求的对象格式 二.ClassLoader常用方法 1.define ...
- 2 深入分析 Java IO的工作机制(二)
2.5 I/O调优 下面总结一些磁盘I/O和网络I/O的常用优化技巧. 2.5.1 磁盘I/O优化 1. 性能检测 应用程序通常都需要访问磁盘来读取数据,而磁盘I/O通常都很耗时,要判断I/O是否是一 ...
- 深入分析 Java I/O 的工作机制--转载
Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...
- 深入分析 Java I/O 的工作机制
I/O 问题可以说是当今互联网 Web 应用中所面临的主要问题之一,因为当前在这个海量数据时代,数据在网络中随处流动.这个流动的过程中都涉及到 I/O 问题,可以说大部分 Web 应用系统的瓶颈都是 ...
随机推荐
- int(“1.6”),int(1.6)输出结果?
>>> int("1.6") Traceback (most recent call last): File , in <module> ValueE ...
- 由Java正则表达式的灾难性回溯引发的高CPU异常:java.util.regex.Pattern$Loop.match
问题与分析 某天领导report了一个问题:线上的CPU自从上一个版本迭代后就一直处于居高不下的状况,领导看着这段时间的曲线图判断是有两条线程在不停的死循环. 接到任务后去查看了AWS的CloudWa ...
- Webpack 核心模块 tapable 解析(转)
原文出自:https://www.pandashen.com 前言 Webpack 是一个现代 JavaScript 应用程序的静态模块打包器,是对前端项目实现自动化和优化必不可少的工具,We ...
- GC和GC分配策略
一.内存如何回收 解决如何回收问题,首先需要解决回收对象的问题?什么样的对象需要回收,怎么样的不需要回收?保证有引用的内存不被释放:回收没有指针引用的内存是Collector的职责,在保证没有指针引用 ...
- Node.js 文件操作
1.新建一个文件a.txt,并写入"你好,这是一个新文件.". writeFile 代码 demo1.js var fs = require('fs'); console.log( ...
- linux几种传输方式与拷贝方式的性能分析
本文记录linux系统中文件传输的多种方式,留作备忘.linux中文件传输的方式有ftp,scp,rsync,rz,sz等,但各个工具的功能又有所区别: FTP : FTP是文件服务器,可实现文件的上 ...
- python 了解一点属性的延迟计算
写在前面 本以为百度搜索这类知识的文章应该有很多, 然后我看了前面几篇后,基本上都是类似的内容,我想找些与众不同的博客看下,来拖宽这方面的广度,我就随机点到了第10页,结果第10页的内容基本跟属性的延 ...
- SQL注入自学[第一学:一个简单的注入环境的编写]
/* 转载请注明出处 ID:珍惜少年时 */ CODE区域: /*注:现在mysql_connect的这种连接方式已经被放弃了,也就是说不用了,老夫也是新手上路故,下载了一个wampserver2.2 ...
- myeclipse启动的过程中没提示就自动退出,闪退的有效解决方法
今天遇到一个问题,已经打开myeclipse的电脑因为非正常关机后myeclipse打不开了,进度条进到十分之一就闪退,什么提示都没有的解决方案如下: 1.打开myeclipse工作空间(存放项目 ...
- 随机数据构造-Faker
from faker import Faker # fake = Faker() #本地化处理 fake = Faker('zh_CN') # print(fake.name()) # print(f ...