由于工作并不是很忙,闲暇之余就读了下tomcat的源代码。我是从事java服务器开发工作的,大体的一些服务器线程模型我都是了解的。其大部分都是由一个线程调用监听端口等待客户端的链接,建立连接后再交由其他的线程负责具体的网络io操作。可tomcat居然是用多个线程调用同一个ServerSocket实例的accept方法。我读过mina也读过netty的源码,自己在大学时也写过不少的基于socket通信的程序,但是这种用法自己从未想过也从未见过。(恕本人咕噜寡闻了,-_-|||)不免好奇,这么做原来没问题啊?可这么做能有什么好处吗?

  要明白这么做的道理,恐怖不得不去搞清楚套接字的accept方法底层到底干了什么,与TCP的三步握手又是什么关系。我查了一些资料大体把这些搞明白了,在这里记录下来以加强自己的认识,也同时共享给哪些跟我一样对socket的认识有所偏差的人。

  一、首先说一下TCP三步握手的基本流程,如下图:

  首先,请求端(客户端)发送一个包含SYN标志的TCP报文,SYN即同步(Synchronize),同步报文会指明客户端使用的端口以及TCP连接的初始序号;
  第二步,服务器在收到客户端的SYN报文后,进入SYN-RECEVIED状态并将这个还没有完全建立起的连接放到半连接队列。还要返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgment)。
  第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。服务器端就会把此连接从半连接队列移除放入到完全连接队列。

  注意说到的两个队列:半连接队列和完全连接队列

  二、socket操作和TCP的关系

  也许好多人都是认为,当我们调用ServerSocket的accept方法时,是在监听等待客户端的连接,当客户端请求服务器时就创立连接并返回与客户端通信的socket。实际呢却不是这样子的。我们来看一个现象

首先我们启动一个服务器程序,程序很简单:代码如下

public class Server {

    public static void main(String[] args) throws IOException {
ServerSocket sSocket = new ServerSocket(3661, 2);//第二个参数的含义后边会讲解
System.in.read();//防止程序退出
} }

  可以看到,这里我们并没有调用serversocket的accept方法。如果按上边说的,accept方法是监听端口等待客户单的连接并完成连接的建立的话。我们这个服务器程序根本无法监听端口并完成连接建立。接下来验证一下,

  首先运行服务程序程序,然后我们在命令行下用netstat -an查看一下端口情况:

可以看出端口依然被监听了,并处于tcp三步握手的LISTEN状态。接下来我们连接试试能不能进行连接,启动一个命令行窗口,执行:

  telnet 127.0.0.1 3661。不要把这个关啦,再启动一个命令行窗口执行以下上边的netstat -an命令:

  可以看到,连接已成功建立了,TCP已经进入ESTABLISHED阶段。看以看到,我们不调用accept方法一样可以监听端口并和客户端建立连接。

由此我们可以证明accept方法并不是监听端口等待客户端的连接并建立连接。那是什么起到了监听端口等待客户单连接的作用的,通过看源码我们会发现构造方法调用了bind方法。

  看到这里想必都能知道,其实在我们调用accept返回一个socket时,tcp早已把三步握手的过程完成了,连接已经都建立好了。那我们的accept具体干什么事呢?还记得上边提到的完全连接队列吧。accept就是从完全连接队列取出连接并封装成socket。ServerSocket的构造方法参数backlog就是指定这个队列的大小。比如上边服务器程序我们制定了backlog的值为2,当我们用三个命令行分别调用telnet 127.0.0.1 3661时,我们会发现第三个连接请求将是无法连接。

  

网络编程之socket新解的更多相关文章

  1. 网络编程之socket

    网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...

  2. 网络编程之Socket & ServerSocket

    网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP ...

  3. GO语言的进阶之路-网络编程之socket

    GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...

  4. [深入浅出Cocoa]iOS网络编程之Socket

    http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   [深入浅出Co ...

  5. 网络编程之Socket代码实例

    网络编程之Socket代码实例 一.基本Socket例子 Server端: # Echo server program import socket HOST = '' # Symbolic name ...

  6. [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]

    [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...

  7. Python自动化运维之15、网络编程之socket、socketserver、select、twisted

    一.TCP/IP相关知识 TCP/UDP提供进程地址,两个协议互不干扰的独自的协议       TCP :Transmission Control Protocol 传输控制协议,面向连接的协议,通信 ...

  8. Python网络编程之socket应用

    1 引言 本篇主要对Python下网络编程中用到的socket模块进行初步总结.首先从网络基础理论出发,介绍了TCP协议和UDP协议:然后总结了socket中的常用函数:最后通过实际代码展示基本函数的 ...

  9. 【python之路35】网络编程之socket相关

    Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

随机推荐

  1. C++混合编程之idlcpp教程Lua篇(7)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件: ...

  2. 使用call来实现继承

    function Class1(arg1,arg2) { this.name = arg1; this.pass = arg2; this.showSub = function() { return ...

  3. 【Win10 UWP】微信SDK基本使用方法和基本原理

    上回讲到,作为一个长期散播温暖,散播希望的小清新无公害WP开发者,继QQ SDK之后,又把UWP微信SDK这茬了结了,仅供学习交流. 1.安装微信SDK for UWP 微信官方此前明确说明短时间内暂 ...

  4. 让人一用钟情的VS插件系列之一——Web Essentials(Web开发必备利器)

    返回VS插件总目录 本篇目录 初识Web Essentials 看国外大牛如何评价Web Essentials Web Essentials下载与安装 Web Essentials涉及到了哪些内容 初 ...

  5. 如何让Hadoop读取以gz结尾的文本格式的文件

    背景: 搜索引擎在build全量时,会产生数G的xml的中间文件,我需要去查询这些中间文件中,是否有某个特殊的字符.xml文件有很多,每个都有几百M,存储在hdfs上,而且是以gz结尾的文本格式的文件 ...

  6. Android怎么找到最优适配资源

    当我们将一些提供了不同的资源文件可供Android系统选择的时候,Android会在运行时会根据一套适配的规则选择最符合当前配置的资源.为了说明Android怎么选择资源,假设我们有以下可选的资源文件 ...

  7. SlipHover,能感知鼠标方向的图片遮罩效果jQuery插件

    接上一篇博文,介绍完jQuery插件开发后这里上一个自己的作品,也是初次实践,小有成就的感觉. 话说这个插件年前就写好了,然后挂到GitHub,然后就偷偷看着Google Analysis心中暗自激动 ...

  8. C#学习笔记 -- Attribute

    学习参考: http://www.cnblogs.com/dudu/articles/4449.html http://www.cnblogs.com/anytao/archive/2007/04/1 ...

  9. Linux—解压缩

    压缩和解压("//"命令的解释) 常用压缩格式    .zip    .gz    .bz2    .tar.bz2        .tar.gz .zip格式压缩: zip 压缩 ...

  10. vi 卡住怎么办

    http://zhidao.baidu.com/question/93283359.html ---------- 我貌似好像按了ctrl+s... 用惯了windows人,会习惯性地按Ctrl+S来 ...