第五冶金建设公司职工大学网站,网站建设与规划实验心得,济宁市城市建设投资中心网站,做3d图的网站有哪些软件有哪些常识一#xff1a;文件句柄限制 在linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符#xff0c;一旦这个文件描述符使用完了#xff0c;新的连接到来返回给我们的错误是“Socket/File:Cantopen so many files”。 这时你需要明白操作系统对可以… 常识一文件句柄限制 在linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符一旦这个文件描述符使用完了新的连接到来返回给我们的错误是“Socket/File:Cantopen so many files”。 这时你需要明白操作系统对可以打开的最大文件数的限制。 进程限制 执行ulimit -n 输出1024说明对于一个进程而言最多只能打开1024个文件所以你要采用此默认配置最多也就可以并发上千个TCP连接。 临时修改ulimit -n1000000但是这种临时修改只对当前登录用户目前的使用环境有效系统重启或用户退出后就会失效。 永久修改编辑/etc/security/limits.conf 文件 修改后内容为 * soft nofile 1000000 * hard nofile 1000000 全局限制 执行 cat/proc/sys/fs/file-nr 输出9344 0592026分别为1.已经分配的文件句柄数2.已经分配但没有使用的文件句柄数3.最大文件句柄数。但在kernel2.6版本中第二项的值总为0这并不是一个错误它实际上意味着已经分配的文件描述符无一浪费的都已经被使用了 。 我们可以把这个数值改大些用 root 权限修改 /etc/sysctl.conf 文件: fs.file-max 1000000 net.ipv4.ip_conntrack_max 1000000 net.ipv4.netfilter.ip_conntrack_max 1000000 常识二端口号范围限制 操作系统上端口号1024以下是系统保留的从1024-65535是用户使用的。由于每个TCP连接都要占一个端口号所以我们最多可以有60000多个并发连接。我想有这种错误思路朋友不在少数吧其中我过去就一直这么认为 我们来分析一下吧 如何标识一个TCP连接系统用一个4四元组来唯一标识一个TCP连接{local ip, local port,remoteip,remoteport}。好吧我们拿出《UNIX网络编程卷一》第四章中对accept的讲解来看看概念性的东西第二个参数cliaddr代表了客户端的ip地址和端口号。而我们作为服务端实际只使用了bind时这一个端口说明端口号65535并不是并发量的限制。 server最大tcp连接数server通常固定在某个本地端口上监听等待client的连接请求。不考虑地址重用unix的SO_REUSEADDR选项的情况下即使server端有多个ip本地监听端口也是独占的因此server端tcp连接4元组中只有remoteip也就是client ip和remoteport客户端port是可变的因此最大tcp连接为客户端ip数×客户端port数对IPV4不考虑ip地址分类等因素最大tcp连接数约为2的32次方ip数×2的16次方port数也就是server端单机最大tcp连接数约为2的48次方。 要写网络程序就必须用Socket这是程序员都知道的。而且面试的时候我们也会问对方会不会Socket编程一般来说很多人都会说Socket编程基本就是listenaccept以及sendwrite等几个基本的操作。是的就跟常见的文件操作一样只要写过就一定知道。对于网络编程我们也言必称TCP/IP似乎其它网络协议已经不存在了。对于TCP/IP我们还知道TCP和UDP前者可以保证数据的正确和可靠性后者则允许数据丢失。最后我们还知道在建立连接前必须知道对方的IP地址和端口号。除此普通的程序员就不会知道太多了很多时候这些知识已经够用了。最多写服务程序的时候会使用多线程来处理并发访问。我们还知道如下几个事实1。一个指定的端口号不能被多个程序共用。比如如果IIS占用了80端口那么Apache就不能也用80端口了。2。很多防火墙只允许特定目标端口的数据包通过。3。服务程序在listen某个端口并accept某个连接请求后会生成一个新的socket来对该请求进行处理。于是一个困惑了我很久的问题就产生了。如果一个socket创建后并与80端口绑定后是否就意味着该socket占用了80端口呢如果是这样的那么当其accept一个请求后生成的新的socket到底使用的是什么端口呢我一直以为系统会默认给其分配一个空闲的端口号如果是一个空闲的端口那一定不是80端口了于是以后的TCP数据包的目标端口就不是80了--防火墙一定会组织其通过的实际上我们可以看到防火墙并没有阻止这样的连接而且这是最常见的连接请求和处理方式。我的不解就是为什么防火墙没有阻止这样的连接它是如何判定那条连接是因为connet80端口而生成的是不是TCP数据包里有什么特别的标志或者防火墙记住了什么东西后来我又仔细研读了TCP/IP的协议栈的原理对很多概念有了更深刻的认识。比如在TCP和UDP同属于传输层共同架设在IP层网络层之上。而IP层主要负责的是在节点之间End to End的数据包传送这里的节点是一台网络设备比如计算机。因为IP层只负责把数据送到节点而不能区分上面的不同应用所以TCP和UDP协议在其基础上加入了端口的信息端口于是标识的是一个节点上的一个应用。除了增加端口信息UPD协议基本就没有对IP层的数据进行任何的处理了。而TCP协议还加入了更加复杂的传输控制比如滑动的数据发送窗口Slice Window以及接收确认和重发机制以达到数据的可靠传送。不管应用层看到的是怎样一个稳定的TCP数据流下面传送的都是一个个的IP数据包需要由TCP协议来进行数据重组。所以我有理由怀疑防火墙并没有足够的信息判断TCP数据包的更多信息除了IP地址和端口号。而且我们也看到所谓的端口是为了区分不同的应用的以在不同的IP包来到的时候能够正确转发。TCP/IP只是一个协议栈就像操作系统的运行机制一样必须要具体实现同时还要提供对外的操作接口。就像操作系统会提供标准的编程接口比如Win32编程接口一样TCP/IP也必须对外提供编程接口这就是Socket编程接口--原来是这么回事啊在Socket编程接口里设计者提出了一个很重要的概念那就是socket。这个socket跟文件句柄很相似实际上在BSD系统里就是跟文件句柄一样存放在一样的进程句柄表里。这个socket其实是一个序号表示其在句柄表中的位置。这一点我们已经见过很多了比如文件句柄窗口句柄等等。这些句柄其实是代表了系统中的某些特定的对象用于在各种函数中作为参数传入以对特定的对象进行操作--这其实是C语言的问题在C语言里这个句柄其实就是this指针实际就是对象指针啦。现在我们知道socket跟TCP/IP并没有必然的联系。Socket编程接口在设计的时候就希望也能适应其他的网络协议。所以socket的出现只是可以更方便的使用TCP/IP协议栈而已其对TCP/IP进行了抽象形成了几个最基本的函数接口。比如createlistenacceptconnectread和write等等。现在我们明白如果一个程序创建了一个socket并让其监听80端口其实是向TCP/IP协议栈声明了其对80端口的占有。以后所有目标是80端口的TCP数据包都会转发给该程序这里的程序因为使用的是Socket编程接口所以首先由Socket层来处理。所谓accept函数其实抽象的是TCP的连接建立过程。accept函数返回的新socket其实指代的是本次创建的连接而一个连接是包括两部分信息的一个是源IP和源端口另一个是宿IP和宿端口。所以accept可以产生多个不同的socket而这些socket里包含的宿IP和宿端口是不变的变化的只是源IP和源端口。这样的话这些socket宿端口就可以都是80而Socket层还是能根据源/宿对来准确地分辨出IP包和socket的归属关系从而完成对TCP/IP协议的操作封装而同时放火墙的对IP包的处理规则也是清晰明了不存在前面设想的种种复杂的情形。明白socket只是对TCP/IP协议栈操作的抽象而不是简单的映射关系这很重要