服务器socket

做了一个web项目,放在服务器上运行一段时间就报错了。

java.net.SocketException: No buffer space available (maximum connections reached?): connect

at java.net.DualStackPlainSocketImpl.connect0(Native Method)

at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)

at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)

at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)

at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)

at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)

at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)

at java.net.Socket.connect(Socket.java:579)

大致查了一下,是说服务器的socket缓存不足,无法创建新的socket。

问题分析:

1.Windows 服务器运行自动更新, 消耗系统很多的 SOCKET 连接 (更新已关闭,错误依然发生)

2.机器中了木马(已做检测,无病毒木马)

3.虚拟内存配置过低(现在配置为8G)

4.有不当程序创建了大量的短连接,由于程序的不健壮,导致 SOCKET 处于忙碌或者 TIME_WAIT 状态,或者服务器和客户端有一方出现异常,而另一方没有得到通知,还在连接,持续不断的做写操作 (无大量Socket 连接,高峰时间有8-10个 TIME_WAIT 状态的连接) 
    
       5:系统中JDBC,JMS,WebServices,socket 都确认进行了关闭

那么下看看具体情况呢

在dos窗口下敲入:

netstat -an    查看一下是否确实是socket大量的资源被占用

也可以通过命令:netstat -b,查看一下哪些connect处于wait状态:

TCP端口状态,有ESTABLISHED、TIME_WAIT几种状态,它们分别是;

TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。

网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得注意的状态有两个:CLOSE_WAIT和TIME_WAIT。  
1、LISTENING状态
  FTP服务启动后首先处于侦听(LISTENING)状态。

2、ESTABLISHED状态
  ESTABLISHED的意思是建立连接。表示两台机器正在通信。

3、CLOSE_WAIT

对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

4、TIME_WAIT

我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。

目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

5、SYN_SENT状态

  SYN_SENT状态表示请求连接,当你要访问其它的计算机的服务时首先要发个同步信号给该端口,此时状态为SYN_SENT,如果连接成功了就变为ESTABLISHED,此时SYN_SENT状态非常短暂。

但如果发现SYN_SENT非常多且在向不同的机器发出,那你的机器可能中了冲击波或震荡波之类的病毒了。这类病毒为了感染别的计算机,它就要扫描别的计算机,在扫描的过程中对每个要扫描的计算机都要发出了同步请求,

这也是出现许多SYN_SENT的原因。

发现了问题,解决它

1,关闭掉使用该connect的应用程序或者直接从进程中kill掉。

2,调整os的tcp/ip的延迟等待时间参数,可以减少状态为:time_wait的连接:【TcpTimedWaitDelay】由默认值240s调为30s

Windows2003的tcp/ip调整可以参见如下: 
1>.启动注册表编辑器。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 
2>.添加参数: 
(1)新建 
值名称:MaxUserPort 
值类型:DWORD 
值数据:65534(十六进制是FFFE) 
有效范围:5000 - 65534 (十进制) 
默认:0x1388 5000(十进制) 
(2)新建 
值名称:TCPTimedWaitDelay 
值类型:DWORD 
值数据:0000001e(30) 
3、调整windows的虚拟内存,建议加大,并查看磁盘空间是否足够划分出虚拟内存。

服务端,端口的状态变化
  先在本机(IP地址为:192.168.1.10)配置FTP服务,然后在其它计算机(IP地址为:192.168.1.1)访问FTP服务,从TCPView看看端口的状态变化。
下面黑体字显示的是从TCPView中截取的部分。
1、LISTENING状态
  FTP服务启动后首先处于侦听(LISTENING)状态。
  State显示是LISTENING时表示处于侦听状态,就是说该端口是开放的,等待连接,但还没有被连接。就像你房子的门已经敞开的,但还没有人进来。
  从TCPView可以看出本机开放FTP的情况。它的意思是:程序inetinfo.exe开放了21端口,FTP默认的端口为21,可见在本机开放了FTP服务。目前正处于侦听状态。
  inetinfo.exe:1260 TCP 0.0.0.0:21 0.0.0.0:0 LISTENING
2、ESTABLISHED状态
  现在从192.168.1.1这台计算机访问一下192.168.1.10的FTP服务。在本机的TCPView可以看出端口状态变为ESTABLISHED。
  ESTABLISHED的意思是建立连接。表示两台机器正在通信。
  下面显示的是本机的FTP服务正在被192.168.1.1这台计算机访问。
  inetinfo.exe:1260 TCP 192.168.1.10:21 192.168.1.1:3009 ESTABLISHED
  注意:处于ESTABLISHED状态的连接一定要格外注意,因为它也许不是个正常连接。后面我们要讲到这个问题。
3、 TIME_WAIT状态
  现在从192.168.1.1这台计算机结束访问192.168.1.10的FTP服务。在本机的TCPView可以看出端口状态变为TIME_WAIT。
  TIME_WAIT的意思是结束了这次连接。说明21端口曾经有过访问,但访问结束了。
  [System Process]:0 TCP 192.168.1.10:21 192.168.1.1:3009 TIME_WAIT
4、小技巧
  a、可以telnet一个开放的端口,来观察该端口的变化。比如看1025端口是开放的,在命令状态(如图1运行cmd)运行:
  telnet 192.168.1.10 1025
  b、从本机也可以测试,只不过显示的是本机连本机
  c、在Tcpview中双击连接可看出程序的位置,右键点击该连接,选择End Process即可结束该连接。

客户端端口状态解释

客户端,端口的状态变化
  客户端口实际上就是从本机访问其它计算机服务时打开的源端口,最多的应用是上网,下面就以访问百度为例来看看端口开放以及状态的变化情况。
1、SYN_SENT状态
  SYN_SENT状态表示请求连接,当你要访问其它的计算机的服务时首先要发个同步信号给该端口,此时状态为SYN_SENT,如果连接成功了就变为ESTABLISHED,此时  SYN_SENT状态非常短暂。但如果发现SYN_SENT非常多且在向不同的机器发出,那你的机器可能中了冲击波或震荡波之类的病毒了。这类病毒为了感染别的计算机,它就要扫描别的计算机,在扫描的过程中对每个要扫描的计算机都要发出了同步请求,这也是出现许多SYN_SENT的原因。
  下面显示的是本机连接百度网站时的开始状态,如果你的网络正常的,那很快就变为ESTABLISHED的连接状态。
  IEXPLORE.EXE:2928 TCP 192.168.1.10:1035 202.108.250.249:80 SYN_SENT
2、ESTABLISHED状态
  下面显示的是本机正在访问百度网站。如果你访问的网站有许多内容比如访问天极网,那会发现一个地址有许多ESTABLISHED,这是正常的,网站中的每个内容比如图片、flash等都要单独建立一个连接。看ESTABLISHED状态时一定要注意是不是IEXPLORE.EXE程序(IE)发起的连接,如果是EXPLORE.EXE之类的程序发起的连接,那也许是你的计算机中了木马了。
  IEXPLORE.EXE:3120 TCP 192.168.1.10:1045 202.108.250.249:80 ESTABLISHED
3、TIME_WAIT状态
  如果浏览网页完毕,那就变为TIME_WAIT状态。
  [System Process]:0 TCP 192.168.1.10:4259 202.108.250.249:80 TIME_WAIT

TCP状态转移要点
TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不 会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得 注意的状态有两个:CLOSE_WAIT和TIME_WAIT。

1、LISTENING状态
FTP服务启动后首先处于侦听(LISTENING)状态。

2、ESTABLISHED状态
ESTABLISHED的意思是建立连接。表示两台机器正在通信

3、CLOSE_WAIT

对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

4、TIME_WAIT

我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分 段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情 况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。

目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

5、SYN_SENT状态

   SYN_SENT状态表示请求连接,当你要访问其它的计算机的服务时首先要发个同步信号给该端口,此时状态为SYN_SENT,如果连接成功了就变为 ESTABLISHED,此时SYN_SENT状态非常短暂。但如果发现SYN_SENT非常多且在向不同的机器发出,那你的机器可能中了冲击波或震荡波 之类的病毒了。这类病毒为了感染别的计算机,它就要扫描别的计算机,在扫描的过程中对每个要扫描的计算机都要发出了同步请求,这也是出现许多 SYN_SENT的原因。

根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒,TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.

windows 机器设置
在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,右键添加名为TcpTimedWaitDelay的
DWORD键,设置为60,以缩短TIME_WAIT的等待时间

ubuntu机器设置

vi /etc/sysctl.conf

编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行 /sbin/sysctl -p 让参数生效。

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

查看系统TCP连接资源命令

netstat 

netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}‘

一般情况下,系统的socket资源默认5000个。(非官方)

TCP协议中有TIME_WAIT这个状态
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接。在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

时间: 2024-10-13 12:26:46

服务器socket的相关文章

Android客户端与本地服务器Socket通信

Android客户端与本地服务器Socket通信 Socket服务器运行结果图?? 一.客户端和服务器端的选择: 客户端是我们手机端,关于服务器端,只要安装了JDK,自然就拥有通讯的功能,我们只需要在Eclipse或者MyEclipse中写好文章中服务器端的代码,运行起来即可,用accept()方法启动服务器端,等待客户端的连接,在未连接的情况下,服务器端处于堵塞的状态. 二.客户端注意事项 andriod客户端添加网络访问权限 <uses-permission android:name="

外网客户端访问校园内网的服务器——socket连接

在做客户端与服务器的socket连接并发送数据应用中,通常有以下四种情况: 1).客户端在内网,服务器在内网. 对于这种情况,只需要用服务器的内网IP即可. 2).客户端在外网,服务器在内网. 对于这种情况,服务器可采用花生壳软件来进行外网IP与内网IP的映射. 3).客户端在内网,服务器在外网. 对于这种情况,只需要用服务器的外网IP即可. 4).客户端在外网,服务器在外网. 对于这种情况,只需要用服务器的外网IP即可. 从分析中可以看出,只有情况二是特殊的,由于服务器在内网,而客户端在外网,

socket 服务器 | socket 客户端

# ### socket 服务器 import socket # 创建一个socket对象 sk = socket.socket() # 绑定ip和端口(注册网络,让别人找到你) # "127.0.0.1" 默认本机的ip sk.bind( ("127.0.0.1",9000) ) # 开启监听 (等待别人连接服务器) sk.listen() ''' # 建立三次握手,建立连接 , 程序加了阻塞 , 建立三次握手如果失败,程序不往下执行 ''' conn,addr

Lua 服务器Socket通信实例(转)

local socket = require"socket" local host = "127.0.0.1"local port = "843"local sever = assert(socket.bind(host, port)) --绑定sever:settimeout(nil)   --不设置阻塞local tab = {}table.insert(tab, sever) while 1 do  local s  s,_,_ = soc

JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo

OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七层:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层 TCP/IP协议 TCP/IP是一系列网络通信协议的统称,其中最核心的两个协议是TCP和IP.TCP称为传输控制协议,IP称为互联网络协议. 网络分层除了OSI模型分层,还有TCP/IP模型分层,将网络划分为四层,应用层.传输层.网际层

C# Socket通信的服务器与客户端

客户端代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; namespace ClientSocket { class Program { private static byte[] result = new byte[1024]; s

socket,实现服务器和客户端对话

服务器: #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string>#include<WinSock2.h> //网络库用2.2版本 目前系统的最高版本#pragma comment(lib,"Ws2_32.lib") //加载动态连接库 x32.x64都是用ws2_32.lib这一个版本//上面为第二版 第一版头文件为WinSock.h 动态库为wsock32.libusing

Socket笔记

在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器, 服务器与客户端都通过 Socket 来收发数据. 这篇文章首先介绍Socket类的各个构造方法, 以及成员方法的用法, 接着介绍 Socket的一些选项的作用, 这些选项可控制客户建立与服务器的连接, 以及接收和发送数据的行为. 一. 构造Socket Socket的构造方法有以下几种重载形式:

Linux 网络编程三(socket代码详解)

//网络编程客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h>//htons()函数头文件 #include <ne