【问题标题】:Java Limited connections to serverJava 与服务器的有限连接
【发布时间】:2015-02-06 14:14:31
【问题描述】:

我是 java 新手,尤其是 java 网络新手,但我想做的是设置一个服务器(用于游戏)。当两个客户端连接到服务器时,我想拒绝任何其他连接。我可以关闭 ServerSocket 吗?如果 ServerSocked 关闭,那两个作为线程运行并存储在集合中的连接仍然存在并且能够与服务器通信?我希望你明白我的意思。

这里是源代码:

//Server
public synchronized List<ClientThread> getClients(){
    return clients;
}


public void run() {
    try {
        while(true){

            Socket clsock = srvsock.accept();

            if(getClients().size() == 2){
                System.out.println("Too many connections!");
                clsock.close();
                continue;
            }

            ClientThread clt = new ClientThread(clsock);
            clients.add(clt);
            clt.start();
            System.out.println("Connection accepted.");

        }
    } catch (IOException ex) {
        ex.printStackTrace(System.err);
    }
}

使用此代码,我无法在客户端上检测连接是否仍然存在,或者服务器是否已关闭连接。提前致谢。

【问题讨论】:

  • 我认为它会像你描述的那样工作,但你测试过吗?让您的 ClientThread 使用 BufferedReader 从套接字的输入流中读取,并在读取时输出每一行。然后编写一个测试客户端,逐行写入输出流,每行之间有一个 Thread.sleep。运行您的测试客户端的三个实例,如果(在服务器输出流中)您看到“连接太多”消息,然后是其他两个客户端的输出,那么它可以按您的意愿工作。
  • 谢谢@PaulMedcraft,我会试试的。

标签: java network-programming serversocket


【解决方案1】:

测试客户端代码:

Socket s = new Socket("localhost", 8932);               
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

for (int i=0; i<20; i++) {
    bw.write(String.valueOf(i));
    bw.newLine();
    bw.flush();
    Thread.sleep(1000);
}
bw.close();

对于 ClientThread:

BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
while (true) {
    String misc = in.readLine();
    System.out.println(misc);
    if (misc==null || misc.length()==0)
        break;
}
in.close();

输出:

Connection accepted.
0
Connection accepted.
0
1
Too many connections!
1
2
2
3

所以它按您的预期工作。顺便说一句,通常最好实现 Runnable 而不是扩展 Thread - 请参阅"implements Runnable" vs. "extends Thread"

【讨论】:

  • 不用担心。您可以将 while (true) 更改为 while (clients.size() ,而不是关闭 ServerSocket
  • 我想再问你一个问题。我正在用 GUI 做应用程序。当用户按下创建按钮时,它会以这种方式创建一个线程(我扩展JFrame的GUI类实现了Runnable): Thread t1 = new Thread(this); t1.start();在 run() 方法中,它创建了服务器的实例......在他创建服务器之后,让同一个用户作为客户端是一个好主意吗? t1.start() 之后;我正在这样做:Client cl = new Client("localhost");
  • 所以你有两个玩家,一个提供服务器和一个客户端,一个只充当客户端?听起来有点笨拙。我要么让一个玩家作为客户端,一个作为服务器,要么同时作为单独服务器的客户端。
  • 我试图想象它。 (玩家作为服务器,玩家作为客户端)。如果我错了,请纠正我,但不需要 ClientThread 类,Server 类中的循环也不需要?
  • @PaulMedcraft 我知道这有点随机,但是使用 while(clients.size()
【解决方案2】:

每次建立连接时,服务器都会为下一个连接返回一个新的套接字(当您使用 srvsock.accept() 时)。所以你可以关闭“srvsock”而不影响“clsock”。要测试他们是否还活着,请查看此帖子 How do I check if a Socket is currently connected in Java?。 希望你能解决你的问题。

【讨论】:

  • 我不确定。非常感谢。
  • 我试图在达到两个连接后打破循环,关闭 srvsock 并抛出异常:关闭服务器。 // srvsock.close() 之后的输出; java.net.SocketException: 套接字在 java.net.SocketInputStream.socketRead0(Native Method) 处关闭...
  • 你能粘贴从套接字读取的代码吗?大概是在ClientThread里面?
猜你喜欢
  • 2016-05-20
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多