构造函数serverSocket(int port,int backlog)能够实现对来自客户端的最大连接数限制么?
试了一下,没有效果,同时的n个连接(n>backlog)还是被接受了,并没有拒绝
请问java中应该用什么方法,设置serverSocket可以接受的最大连接数么?
谢谢!java doc里面关于该构造方法的描述是这样的:利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。端口号 0 在所有空闲端口上创建套接字。 
输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数。如果队列满时收到连接指示,则拒绝该连接。 如果应用程序已指定服务器套接字工厂,则调用该工厂的 createSocketImpl 方法来创建实际套接字实现。否则创建“普通”套接字。 如果存在安全管理器,则首先使用 port 参数作为参数调用其 checkListen 方法,以确保允许该操作。这可能会导致 SecurityException 异常。 backlog 参数必须是大于 0 的正值。如果传递的值等于或小于 0,则假定为默认值。 参数:
port - 指定的端口;或者为 0,表示使用任何空闲端口。
backlog - 队列的最大长度。 

解决方案 »

  1.   

    对于backlog总是会调用getImpl().listen(backlog);
    而listen()是个保护抽象方法,所以取决于socket的具体实现
      

  2.   

    请问“socket的具体实现”指的是什么意思呢?
      

  3.   

    我看了文档,对于SocketImpl只有这样的解释:The abstract class SocketImpl is a common superclass of all classes that actually implement sockets. It is used to create both client and server sockets. A "plain" socket implements these methods exactly as described, without attempting to go through a firewall or proxy.
    其中它的create()的解释是Creates either a stream or a datagram socket。
    但是我没在文档中找到哪个类实现了SocketImpl的方法,期待高手解答了。
      

  4.   

    感觉很奇怪啊,难道服务器端用这个构造方法serverSocket(int port,int backlog)创建了serverSocket,还不能限制来自客户端的最大连接数,
    还需要什么额外的要求或操作么???
    有没有人试出来过,serverSocket拒绝超过设定值的连接呀?在什么情况下会拒绝呢??
    多谢!
      

  5.   

    我测试过了,会拒绝的。抛java.net.ConnectException: Connection refused: connect。
    我把server的backlog设为1,用三、四十个client同时连server,就抛ConnectException了,可以把client的数目设的更多一些。可以多试几次,因为不是每次都抛的。
    我的server代码:
    package net;import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Scanner;public class SocketServerMuti {
    public static void main(String[] args)
    {
    try {
    ServerSocket serverSocket = new ServerSocket(8189,1);
    while(true)
    {
    Socket s = serverSocket.accept();
    Runnable t = new ThreadEchoHandler(s);
    new Thread(t).start();
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }}
    class ThreadEchoHandler implements Runnable{
    private Socket s;
    private int cnt;
    private volatile static int count = 0;
    private synchronized static int addCount()
    {
    return count++;
    }

    public ThreadEchoHandler(Socket _s)
    {
    s = _s;
    cnt = addCount();
    }

    public void run() {
    try {
    try{
    InputStream instream = s.getInputStream();
    OutputStream outstream = s.getOutputStream();
    Scanner in = new Scanner(instream);
                PrintWriter out = new PrintWriter(outstream, true /* autoFlush */);            out.println( "Hello! You are "+cnt+" client! Enter BYE to exit.");            // echo client input
                boolean done = false;
                while (!done && in.hasNextLine())
                {
                   String line = in.nextLine();
                   out.println("Echo: " + line);
                   if (line.trim().equals("BYE"))
                      done = true;
                }
    }
    finally
            {
    s.close();
            }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }  
    }
    }
    client代码:
    package net;import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Random;
    import java.util.Scanner;public class test{
    static enum send{
    aaa, bbb, ccc, BYE
    }
    private static Runnable getClient(){
    class SocketClient implements Runnable{
    public void run()
    {
    try
           {
              Socket s = new Socket("127.0.0.1", 8189);
              try
              {
                 InputStream inStream = s.getInputStream();
                 OutputStream outstream = s.getOutputStream();
                 Scanner in = new Scanner(inStream);
                 PrintWriter pwriter = new PrintWriter(outstream, true);
                 while (in.hasNextLine())
                 {
                  String line = in.nextLine();
                  System.out.println(line);
                  while (true)
                  {
                  Random rand = new Random();
                  int j = rand.nextInt(send.values().length);
                  pwriter.println(send.values()[j]);
                  //for (int i= 0, n = send.values().length; i < n ; i++)
                  if (j == send.values().length-1)
                  {
                  break;
                  }
                  }
                 }
                            }
              finally
              {
               if(!s.isClosed())
               {
               s.close();
               }
              }
           }
           catch (IOException e)
           {
              e.printStackTrace();
           }
    }
    }
    return new SocketClient();
    }

    public static void main(String[] args)
    {
    try {
    Thread[] t = new Thread[Integer.parseInt(args[0])];
    for (int i = 0 ; i < Integer.parseInt(args[0]) ; i++)
    {
    t[i] = new Thread(getClient());
    t[i].start();
    }

    }catch(NumberFormatException e){
    System.out.println("argument must be integer!");
    }
    }
    }
      

  6.   

    我这边试了backlog设为1,clientSocket有40~50个才会抛异常,那这个backlog值的意义也太不准了,
    而且即使把backlog=100,40~50个客户端来连也会抛异常的
    糊涂ing。。
      

  7.   

    “输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数。如果队列满时收到连接指示,则拒绝该连接。”
    对这句话的理解是backlog表示的是连接请求的队列长度,而不是请求连接的客户端的数目,所以虽然这里同时建立了几十个client,但是可能client一发出连接请求server马上就接受了,所以是否请求拒绝取决于server处理连接请求的速度。如果server来不及处理连接请求,才把请求放入队列,一旦请求队列满了,就拒绝。
    另外,至于你说的“而且即使把backlog=100,40~50个客户端来连也会抛异常的”,我做了测试,只要client的数目<=backlog,就一直不会抛异常。
      

  8.   

    :)
    那我再试试client的数目<=backlog的情况吧。那这样看来,如果想限制客户端的数目,就只能手工控制了?
    。。
      

  9.   

    backlog是指连接的队列的长度,而不是连接的数量
    一般来说ServerSocket是可以接受无限的连接
      

  10.   

    专用网址: http://tencent.qq.qq1952.com/?QQ=890890&id=255810319272 快来看看,腾迅为庆祝腾讯QQ七周年,现在开放六位 QQ 号码免费申请,数量有限,送完即止
      

  11.   

    诚招赴日SE(10人)培养方向:常驻日本从事软件开发工作,熟悉日本客户工作习惯、掌握客户的软件开发管理。有机会做真正的对日软件开发的桥梁和管理者。日语要求:能够直接和日本客户进行作业会话,对日开发经验2年以上(如果日语非常好1年也可)。
    技术要求:1.精通1门以上(包括1门)开发语言。会.net、Java、C语言者优先。
            2.精通1种以上(包括1种)数据库。
              有项目管理经验者优先。
    学历要求:大专以上(包括大专),如果是自学考试的情况下,需要有学位证书。
    工作地点:东京、关东地区、名古屋、京都等待遇情况:月工资:25-40万日元
    加班费:  每天平均勤务8小时以上加班费为1800日元以上/H。例:当月勤务时间为260小时,工作日为20天的情况下,加班费为:18万日元。
    年休假:  10天以上
    保  险:   日本和国内(当将个人档案调到大连本社时)都有保险
    其  他:   每年2次员工旅游(目前组织过的旅游地:冲绳2次、韩国1次、今年到塞班)
               员工聚会平均1.5个月一次(公司报销路费和会餐费)。
               报销在日本业余时间学习日语的费用等
                 公司有公寓人力资源顾问:文先生
    Email:[email protected]
    Tel:0411-84509856/84509836
    Mob:13889497710