tcp 服务器响应端口,TCP/HTTP连接/Socket/端口
一、TCP连接与端口
web服务器只开启了一个端口,他是如何为多用户服务的?
问题描述
不同主机之间通讯,必须依赖套接字,而端口号是套接字的标识(开始是这样认为的),那么假设web服务器进程,开启了80端口号(即监听80端口号),接着客户端浏览器,打开任意端口,发起TCP连接请求,服务器80端口监听到请求,建立TCP连接,最后通过客户端套接字和服务器套接字进行通信,那么其他用户怎么办? 80端口也被占用,改如何建立TCP连接?现实中大家发送http请求好像都可以使用一样的端口,如80。
问题解决
首先,明确几点:
1、TCP套接字的唯一标识是一个四元组(源IP地址,源端口号,目的IP地址,目的端口号)
2、TCP创建连接,会进行“三次握手”,
我们这里暂且把TCP建立连接的报文段称为:称为TCP连接
把TCP承载请求数据的报文段称为:TCP请求
客户端浏览器和web服务器的通信过程是这样的:
在建立连接阶段:
浏览器进程打开任意端口,所有的浏览器都是将TCP连接报文,发送给服务器进程监听的端口(如:80),服务器接受到请求,为每个请求创建新的套接字(依据请求报文的源ip,源端口号和自己的ip、端口号)
在发送http请求阶段:
此时连接已经建立,承载了 Http请求信息的TCP请求报文会发送到对应的套接字
因此: 多个不同的套接字可以拥有相同的目的端口号80,由于源ip或端口号不同,TCP套接字就可以唯一标识,通信就可以进行。
同时,一个端口号只能被一个进程所监听
举一反三:其实所有使用TCP的应用程序对的通信都是一样的,分为建立连接和发送数据阶段。
在建立连接时,对于 客户端TCP套接字还没有形成,服务器端进程也是如此,它只是监听80端口而已,把所有目的端口号为80的TCP报文段统统接收,然后去处理,即建立套接字,为套接字分配处理进程。当连接建立时,对应着服务器、客户端套接字的形成,之后的通信,不会将TCP报文段在发送给监听80端口的服务器进程,而是发给与连接对应的套接字,它的目的端口号也是80,但他只是套接字的一部分。
对于服务器进程也是不一样的:一个专门用于建立连接,它监听端口,创建用于连接的套接字
一个专门用于处理请求,通过新建立的套接字发送和接收请求
最好再次总结
1.一个端口同一时间只能bind给一个SOCKET。就是同一时间一个端口只可能有一个监听线程
2.为什么一个端口能建立多个TCP连接,同一个端口也就是说 server ip和server port 是不变的。那么只要[client ip 和 client port]不相同就可以了。能保证接唯一标识[server ip, server port, client ip, client port]的唯一性。
端口号不是套接字的唯一标识。另外,UDP套接字是(目的ip地址,目的端口号),
二、TCP端口(客户端-服务端)
关于TCP服务器最大并发连接数有一种误解就是“因为端口号上限为65535,所以TCP服务器理论上的可承载的最大并发连接数也是65535”。
先说结论:对于TCP服务端进程来说,他可以同时连接的客户端数量并不受限于可用端口号。并发连接数受限于linux可打开文件数,这个数是可以配置的,可以非常大,所以实际上受限于系统性能。
从理论上说,端口号的作用是在网络连接中标识应用层的进程,服务端一般使用众所周知的端口号进行监听,客户端连接时系统自动分配端口号。一个服务端进程服务于n个客户远程进程,只需要能通过ip地址+端口号的组合把他们区分开即可,没有必要占用本机的其他端口号,客户端连接数增加并不会占用服务器端口号,因此端口号并不能限制并发连接数。当然一台机器上端口号数量的上限确实是65536个,因为tcp首部中使用16bit去存储端口号。所以如果说65536影响了连接数,只有一种可能,就是同一台客户端机子上开n个进程去连同一个服务端进程,因为客户端ip是同一个,为了区分出这些连接,只能使用客户端连接的端口号,那么服务端和一个客户端主机之间的tcp连接数理论上线确实是65536。但是,服务端可以连接n多客户端机子呢。
实际上,确实有个限制端口号的配置,就是MaxUserPort,这实际上是一台主机向外连接使用端口数的限制,这个数也可以配置的,可能默认值才5000,实际上对于正常的服务器主机是够用的,因为你是等别人连接进来的,不是要去连接很多不同的其他主机的。当然你的服务器上可能跑了一些转发的服务,这样你就需要对外连接了,如果被限制在这个配置这儿了确实需要改。但是这个MaxUserPort确实和服务器可以承载的来自客户端的并发连接数没有关系。
伴随这个误解的还有另外一个误解,就是accept之后产生的已连接套接字占用了新的端口。这个绝对是错误的,linux内核不会这么写的,因为完全没必要嘛。客户端连接上来之后产生的这个socket fd就是用来区分客户端的,里面会填上客户端的ip和端口作为发包用,来自客户端的包也会使用这个fd去读取。可以试试netstat -ano,然后起一个服务器看下,客户端连上来这后产生的套接字的服务端端口还是监听的端口。
三、HTTP连接
浏览器发送的请求是复用同一个连接吗?
不一定。
发的不同域名,肯定不复用。
发的同域名。若第一个请求与第二个请求并行发送,不复用。
发的同域名,并且是第一个请求完事了才发第二个请求。则看是否有 connection: keep-alive 请求头,没有则不复用。
发的同域名,第一个请求完了后发第二个请求,有 connection: keep-alive 请求头。则复用同一个 TCP 连接。
补充说明
HTTP 1.1 里大概规范了几项提高性能的手段:
持久连接 (keep-alive/persistent connection)
并行连接
Pipelining
持久连接
每一个请求都会重新建立一个 TCP 连接,一旦响应返回,就关闭连接。 而建立一个连接,则需要进行三次握手。HTTP 1.1 出了一个请求头 connection,默认 keep-alive,告诉服务器不关闭 TCP 连接。
并行连接
由于现代网页通常包含了复数个(>=10)资源,而按照默认设定,一个连接中的每一个请求必须等待收到响应后才能发送下一个请求,所以如果复数的资源请求全部在一个连接 one by one 发送给服务器显然会很慢,而为了弥补这一缺陷,浏览器通常会默认开启多个 TCP 连接,然后再根据每个连接的状态在其中依次发送数据请求,而且客户端有权任意关闭超发的连接。各个浏览器允许的并行连接数大致是这样的(From SO):
Firefox 2: 2
Firefox 3+: 6
Opera 9.26: 4
Opera 12: 6
Safari 3: 4
Safari 5: 6
IE 7: 2
IE 8: 6
IE 10: 8
Chrome: 6
由于 TCP 协议本身有慢启动的特征,会随着时间调谐连接的最大速度,因此在现代浏览器中持久连接和并行连接通常是搭配在一起使用的—— 一方面由于持久连接的存在,每个 TCP 连接已经处于调谐后的状态,另一方面持久连接可以避免重新三次握手的开销。
在 Chrome 中,页面初始并行加载一堆静态资源是会最大开 6 个 TCP 连接去并行运作,其后发 Ajax 请求则是复用之前的 TCP 连接。
Pipelining
按照 HTTP 1.1 的描述,还有种可以提升性能的方案是管道化,可以在一个 TCP 连接中并行执行多个请求并返回。
因为这项技术比较复杂,如何能在一个 TCP 中有序的处理所接收到的包,并且不会乱序返回,这在早期没有规范,所以各大浏览器都没有支持此功能,形同鸡肋。
关于 HTTP 2
HTTP 2 为了性能做了不少努力,比如提供了规范以支持连接的多路复用。
如前文所说,在同一个 TCP 连接里面同时发生两个请求响应就不是那么简单。而 HTTP 2 正是提供了这样的规范,可以给数据拆成包,并打上包的顺序标签以供 TCP 能正确认知接收的包的顺序。
所以很多网络优化的知识已经过时
因为“所有的 HTTP 2.0 的请求都在一个 TCP 链接上”,“资源合并减少请求”,比如 CSS Sprites ,多个 JS 文件、CSS 文件合并等手段没有效果,或者说没有必要。
因为“多路复用”,采用“cdn1.cn,cdn2.cn,cdn3.cn,打开多个 TCP 会话,突破浏览器对同一域名的链接数的限制”的手段是没有必要的。因为因为资源都是并行交错发送,且没有限制,不需要额外的多域名并行下载。
因为“服务器推送”,内嵌资源(如base64的图片)的优化手段也变得没有意义了。而且使用服务器推送的资源的方式更加高效,因为客户端还可以缓存起来,甚至可以由不同的页面共享(依旧遵循同源策略)
tcp 服务器响应端口,TCP/HTTP连接/Socket/端口相关推荐
- jmeter测试TCP服务器/模拟发送TCP请求
jmeter测试TCP服务器,使用TCP采样器模拟发送TCP请求. TCP采样器:打开一个到指定服务器的TCP / IP连接,然后发送指定文本并等待响应. jmeter模拟发送TCP请求的方法: 1. ...
- python tcp服务器_python实现TCP服务器端与客户端的方法详解
本文实例讲述了python实现TCP服务器端与客户端的方法.分享给大家供大家参考.具体如下: TCP服务器程序(tsTserv.py): from socket import * from time ...
- udp和tcp是服务器响应,HTTP,TCP,UDP的理解和使用
参考资料 http://www.jianshu.com/p/1ae1170b9a9a Android开发进阶 一.Http理解 Http是一种应用层的协议,它基于TCP协议来进行数据传输.HTTP传输 ...
- TCP服务器和客户端的创建(socket/socketserver)
1 本文记录针对python网络编程学习过程中的socket部分进行记录与总结,内容仅仅涉及最粗浅的部分,日后或许会进行更新与扩展. 2 本文涉及的socket数据传输均使用bytes类型,因此在py ...
- python tcp服务器_Python 创建TCP服务器的方法
问题 你想实现一个服务器,通过TCP协议和客户端通信. 解决方案 创建一个TCP服务器的一个简单方法是使用 socketserver 库.例如,下面是一个简单的应答服务器: from socketse ...
- 金蝶服务器响应异常,金蝶提示连接金蝶云服务器异常
金蝶提示连接金蝶云服务器异常 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 云 ...
- linux 端口耗尽,短连接以致端口耗尽
场景回放 A机器的服务请求B机器的服务 短连接请求,动态创建连接端口 A机器服务会主动关闭连接 短时间内高并发请求 A机器的tcpssports被耗尽了 大部分网络连接处time_wait状态 内核配 ...
- bsd协议开源框架tcp服务器,搬运RT Thread中BSD Socket实现UDP及TCP例子
/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * ...
- python tcp服务器并发_python tcp并发服务器
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
最新文章
- NVIDIA团队:利用神经网络生成极慢视频
- Dubbo与SpringBoot整合流程(从实例入手,附代码下载)
- 钉钉猛增40倍流量压力,阿里云DBA如何应对?
- sqlyog软件的使用
- 神马是代码简单的cmd模式,这就是!
- javascript乘法和加法_js 大整数加法、乘法、除法
- 24 MM配置-采购-配额管理-定义编码范围
- python学习与数据挖掘_python机器学习与数据挖掘
- 用AndroidStudio和vsCode运行ReactNative项目
- IntelliJ IDEA连接mysql
- 什么是网站物理结构、逻辑结构
- 使用WWWGrep检查你的网站元素安全
- 经典C语言从入门到入坑必学最简单的代码
- 联机侠控制台JAVA_我的世界MultiMc启动器
- 微信小程序PDF下载方案
- cadence 旋转快捷键_cadence常用快捷键自己总结
- web前端入门到实战:CSS颜色、背景和剪切
- HDU 6105 Gameia 树上博弈(思路题)(内附官方题解)
- TI高精度实验室-运算放大器-第七节-共模抑制和电源抑制
- typescript是什么_为什么不应该害怕TypeScript