如何停止相同连接的while循环的连续执行

时间:2019-04-08 09:38:36

标签: java sockets networking

我正在为Java中的聊天应用服务器。

while循环应该连接到新客户端,但是即使连接后,代码仍会重复连接到第一个客户端,从而导致Bind Failed错误。我应该改变什么?

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ServerM
{   
    public static void main(String args[])
    {
        while(true)
        {
            Listener l = new Listener();
            l.run();
        }
    }

}

class Listener implements Runnable
{
    static InetAddress arr[] = new InetAddress[10];
    static int i = 0;

    public void run()
    {

        try
        {
            ServerSocket ss = new ServerSocket(44444);
            System.out.println("Waiting...");
            Socket s = ss.accept();
            System.out.println("Connected!\n");

            DataInputStream din=new DataInputStream(s.getInputStream());
            String ip = din.readUTF();

            InetAddress addr = InetAddress.getByName(ip);

            for(int j=0; j<=i; j++)
            {
                if(arr[j] == addr)
                    return;
            }

            arr[i++] = addr;

            ChatThread c = new ChatThread(addr,s);//This creates a thread to allow communication with Client
            c.run();

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您的问题在于解决方案的设计。您正在运行服务器套接字的多个实例(并使用同一端口,否则将以异常结束),并使用该线程获取客户端连接,因此只能有一个连接。

您应该做的是,为服务器套接字运行一个线程,该线程将侦听所有连接,然后在无限循环中运行每个客户端实例(新线程)。

public class ServerM
{   
    public static void main(String args[])
    {

        Listener l = new Listener();
        l.run();

    }

}

class Listener implements Runnable
{
    static InetAddress arr[] = new InetAddress[10];
    static int i = 0;

    public void run()
    {

        try
        {
            ServerSocket ss = new ServerSocket(44444);
            System.out.println("Waiting...");
            while (true) {
                Socket s = ss.accept();
                ClientListener clientListener = new ClientListener(s);
                clientListener.run();
            }

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

class ClientListener implements Runnable {

    private Socket socket;

    public ClientListener(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        System.out.println("Connected!\n");

        DataInputStream din=new DataInputStream(s.getInputStream());
        String ip = din.readUTF();

        InetAddress addr = InetAddress.getByName(ip);

        for(int j=0; j<=i; j++)
        {
            if(arr[j] == addr)
                return;
        }

        arr[i++] = addr;

        ChatThread c = new ChatThread(addr,socket);
        c.run();
    }

}

之所以必须这样做,是因为您只需要一个ServerSocket实例在特定端口上侦听新连接,然后就需要[1..n]个客户端实例来处理每个连接。

答案 1 :(得分:0)

捕获异常是不明智的做法

 catch(Exception e)
    {
        e.printStackTrace();
    }

尝试将自定义异常(MyException.class)转发到顶层,并在try..catch中的ServerM类中处理此异常。而且不要忘了在finally块中关闭套接字

ss.close();
s.close();