我正在为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();
}
}
}
答案 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();