为什么有监听socket和连接socket,为什么产生两个socket

先看一半的socket建立连接的双方的过程:

客户端:

socket()---->创建出 active_socket_fd (client_socket_fd)

bind()--->把active_socket_fdip,port绑定起来

connect()--->client_socket_fd 主动请求服务端的 listen_socket_fd

read()/write()---->读/写 socket io

close()---->关闭socket_fd

服务端:

socket()---->创建出 active_socket_fd

bind()--->把active_socket_fd与ip,port绑定起来

listen()---->active_socket_fd--> listen_socket_fd 等待客户端的client_socket_fd来请求连接

accept()---->listen_socket_fd-->connec_socket_fd 把监听socket转变为连接socket,用于建立连接购的读写数据

read()/write()---->读/写 socket io

close()---->关闭socket_fd

linux内核, socket函数创建的套接字是主动套接字

一开始socket函数, 不管在客户端还是在服务端, 创建的都是主动socket, 但是在服务端经过listen(), 后把其转变为listen_socket_fd(被动监听socket),
经过accept()后转变为connect_socket_fd(已连接socket).

在转变为connect_socket_fd之前, 都是同一个socket, 只不过是socket的状态改变了, 但是服务端经过accept()后返回的socket是新的socket, 用于连接后的read()/write()

为什么服务端这么特殊, 需要两种状态的socket, 并且在这个过程中产生两个socket?

需要两种状态的socket?

对于前者, 这个比较好理解, 因为是现在的网络程序中是C/S结构的, 一般是客户端主动向服务端请求建立连接. 这个过程中, 主要涉及到两个状态, 一个是主动, 一个是被动的. 因此, 客户端的socket只用于主动向服务端的socket请求建立连接, 服务端的socket一直被动的等待客户端的请求连接就ok了. 所以这就解答了为什么需要两种状态的socket, 只有一方是主动, 另一方是被动, 才能否完成上面的过程. 如果双方都是主动, 或者被动, 就完成不了上面的过程了.

1.产生两个socket?

等等, 上面好像没有说到为什么服务端需要产生两个socket(监听socket和已连接socket)

这个我认为是, 监听socket,是服务器作为客户端连接请求的一个对端,只需创建一次能够让客户端请求到有这个端点就ok,所以监听socket(listen_socket_fd)存在于服务器的整个生命周期, 不需要每个连接都创建一个新的监听socket出来, 没必要呢。已连接socket(connect_socket_fd)是客户端与服务器之间已经建立起来了的连接的一个端点,服务器每次接受连接请求时都会创建一个新已连接socket,它的生命周期只是客户端请求服务端的时间范围内。

2.为什么不只使用一个listen_socket_fd完成从创建监听socket(listen_socket_fd), 到被请求连接, 处理请求, 关闭socket的整个过程呢? 而需要用一个listen_socket_fd作为监听客户端请求, 然后每个连接创建一个新的connect_socket_fd来完成服务端与客户端的"交流"?
  • 假设前者那种情况, 只用一个socket完成整个过程. 那么这个socket就会一直被占用, 而不能被另外的客户端请求, 造成了服务端的性能极其低下, 如果没有存储后面的客户端请求, 就会被错过而丢弃, 因为当前的socket正在与当前一个客户端的socket建立连接.
  • 所以从上面的情况可以得知, 在请求连接和连接后需要的socket应该不是同一个, 它们负责的工作是不一样的. 有了listen_socket_fd和connect_socket_fd后, 就可以专门用一listen_socket_fd负责响应客户端的请求, 每次新的connect_socket_fd专门负责当前这次连接的数据交互.

总结

为什么需要两种socket(监听socket和已连接socket)已经说得明白了, 总的来说是, 是为了职责分工, 分层协作, 提高服务端性能.

为什么有监听socket和连接socket,为什么产生两个socket的更多相关文章

  1. oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接

    oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接 oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接 or ...

  2. Android 监听 Android中监听系统网络连接打开或者关闭的实现代码

    本篇文章对Android中监听系统网络连接打开或者关闭的实现用实例进行了介绍.需要的朋友参考下 很简单,所以直接看代码 复制代码 代码如下: package xxx; import android.c ...

  3. DatagramSocket(邮递员):对应数据报的Socket概念,不需要创建两个socket,不可使用输入输出流。

    UDP编程: DatagramSocket(邮递员):对应数据报的Socket概念,不需要创建两个socket,不可使用输入输出流. DatagramPacket(信件):数据包,是UDP下进行传输数 ...

  4. erlang怎样有效监听大量并发连接

    看了erlang的一些开源网络框架RabbitMQ.Ranch.他们都使用多个进程同一时候accept一个socket. 这样的方式在使得socketport监听的工作分担了很多其它的调度机会.可是, ...

  5. plsql启动提示监听服务无法连接

    话说现在用的oracle少了,本人菜鸟一个,但是我真心的没有感觉到它用的少了,今天入了一个新项目,数据库使用的还是oracle,经理二话不说的给了一些东西,说了让一句你把环境啥地 配置一下,然后走人了 ...

  6. [转]netstat -tnl 列出监听中的连接,查看端口是否开启

    任何网络服务的后台进程都会打开一个端口,用于监听接入的请求. 这些正在监听的套接字也和连接的套接字一样,也能被 netstat 列出来. 参数 tnl, 现在我们可以看到处于监听状态的 TCP 端口和 ...

  7. Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)

    Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚 使用场景: 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动 ...

  8. android设置软键盘搜索键以及监听搜索键点击时发生两次事件的问题解决

    在输入框中加入android:imeOptions="actionSearch",调用软键盘时,回车键就会显示搜索二字. 我想在点击搜索时,跳转到下一个页面,但是调用setOnKe ...

  9. shell基础知识---与监听服务器长连接端口状态

    从未写过脚本我的最近接了俩脚本的需求,就在这分享一下我的我学到基础知识主要就四部分内容 一.变量 变量的定义 string='字符串' string="字符串" num=808st ...

  10. Android 实时监测(监听)网络连接状态变化

    http://blog.csdn.net/mxiaoyem/article/details/50708052

随机推荐

  1. linux(rhel) rescue修复详解

    修复linux,先准备好一张安装光盘,光驱安装好后开机,选择从光驱启动.等待安装盘显示操作界面时选择"rescue"选项,如果有光标提示的话,也可以输入:linux rescue进 ...

  2. Vue2.0+ElementUI+PageHelper实现的表格分页

    Vue2.0+ElementUI+PageHelper实现的表格分页 前言 最近做了一些前端的项目,要对表格进行一些分页显示.表格分页的方法有很多,从宏观上来说分为物理分页和逻辑分页,由于逻辑分页(即 ...

  3. 2018.09.28 hdu5434 Peace small elephant(状压dp+矩阵快速幂)

    传送门 看到n的范围的时候吓了一跳,然后发现可以矩阵快速幂优化. 我们用类似于状压dp的方法构造(1(1(1<<m)∗(1m)*(1m)∗(1<<m)m)m)大小的矩阵. 然后 ...

  4. javascript对数组分页

    function pagination(pageNo, pageSize, array) { var offset = (pageNo - 1) * pageSize; return (offset ...

  5. 一个简单的Linux后门程序的实现

    该程序实质是一个简单的socket编程,在受害方上运行攻击代码(后门进程),通过socket打开一个预设端口,并监听,等待攻击方的链接.一旦攻击方通过网络链接工具试图链接该socket,那么后门进程立 ...

  6. 如何更改myecelipse、eclipse的Project Explorer的背景颜色

    这个是我研究了很久发现的,因为myecelipse.eclipse本身是随着系统的颜色改变而改变的,windows系统都会随着系统改变而改变的,所以找了很多资料都没能改变它的背景色,今天发现了一个不错 ...

  7. 20155236 2016-2017-2 《Java程序设计》第七周学习总结

    20155236 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 Calendar是个抽象类,java.util.GregorianCalendar是其子类, ...

  8. Spark RDD详解

    1.RDD是什么 RDD(Resilient Distributed Dataset):是Spark的核心数据结构,指的是一个只读的.可分区的分布式数据集,这个数据集的全部或部分可以缓存在内存中,在多 ...

  9. Paxos与zookeeper

    1,什么是Paxos算法? Paxos算法是分布式计算领域中一个非常重要的算法,主要解决分布式系统如何就某个值(决议)达成一致的问题.一个典型的场景是分布式数据库的一致问题:如果分布式数据库的各个节点 ...

  10. Java内存模型以及Volatile、Synchronize关键字的疑问

    1.众所周知,java的内存模型是一个主内存,每个线程都有一个工作内存空间,那么主内存同步到工作内存是什么时候发生的呢?工作内存同步会主内存又是什么时候发生的呢? 在cpu进行线程切换时就会发生这些同 ...