服务器不适用于多个连接
Server doesn't work with more than one connection
我有一个可以正常工作的简单客户端-服务器应用程序。问题是它只适用于一个启动的客户端,但不适用于两个或更多。它建立连接,但是当您尝试在第一或第二输入文本时,服务器会中断。我认为问题可能出在 Server.java
.
中的函数 broadcast()
Server.java
public class Server {
final int PORT = 5000;
private ArrayList<NewClient> al = new ArrayList<NewClient>();
private Scanner in;
private PrintWriter out;
private SimpleDateFormat sdf;
private int uniqueID = 0;
private void go(){
try{
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Waiting for clients...");
while(true) {
Socket s = serverSocket.accept();
NewClient chat = new NewClient(s);
System.out.println("Client number " + chat.getId() + " connected from: " + s.getLocalAddress().getHostName());
al.add(chat);
Thread t = new Thread(chat);
t.start();
}
}catch (Exception e) {
System.out.println("Problem with establishing network connection: ");
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.go();
}
class NewClient implements Runnable{
private Socket socket;
private int id;
public NewClient(Socket s) {
this.socket = s;
this.id = ++uniqueID;
}
public int getId() {
return this.id;
}
@Override
public void run() {
try{
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
sdf = new SimpleDateFormat("HH:mm:ss");
while(true) {
String input = in.nextLine();
System.out.println("Client said: " + input);
broadcast(input);
}
}catch (Exception e) {
e.printStackTrace();
}
}
private void writeMsg(String input) {
String msg = input + " on " + sdf.format(new Date());
out.println("You said: " + msg);
out.flush();
}
private void broadcast(String input) {
for (int i = 0; i < al.size(); i++) {
NewClient t = al.get(i);
t.writeMsg(input);
}
}
}
}
Client.java:
public class Client {
final int PORT = 5000;
final String HOST = "127.0.0.1";
private Scanner stdIn;
private Scanner in;
private PrintWriter out;
private void go() {
setUpNetwork();
}
private void setUpNetwork(){
try{
Socket s = new Socket(HOST, PORT);
System.out.println("You are connected to " + HOST);
NewClient client = new NewClient(s);
Thread t = new Thread(client);
t.start();
} catch (Exception e) {
System.out.println("Problem with connection to server: " + e);
}
}
public static void main(String[] args) {
Client client = new Client();
client.go();
}
class NewClient implements Runnable {
private Socket socket;
public NewClient(Socket s) {
this.socket = s;
}
@Override
public void run() {
try {
stdIn = new Scanner(System.in);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
while(true) {
System.out.print("> ");
String input = stdIn.nextLine();
out.println(input);
out.flush();
if(in.hasNext()) {
System.out.println(in.nextLine());
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
当打开两个Client.java并连接到server.java时一切正常。但是当我尝试从这两个打开的客户端服务器 returns 发送一些消息时,这些错误:
java.lang.IndexOutOfBoundsException: end
at java.util.regex.Matcher.region(Matcher.java:1038)
at java.util.Scanner.findPatternInBuffer(Scanner.java:1010)
Client said: sds
at java.util.Scanner.findWithinHorizon(Scanner.java:1679)
at java.util.Scanner.nextLine(Scanner.java:1538)
at Server$NewClient.run(Server.java:66)
at java.lang.Thread.run(Thread.java:745)
发生的事情是您的代码从客户端扫描第一行("sds",打印到标准输出),然后循环返回并立即尝试从客户端扫描下一行。由于客户端还没有发送任何东西,输入流扫描器抛出异常。
NewClient class 是一个内部 class。此 class 的所有实例都是使用外部 class 的相同实例创建的。更改代码将解决问题:
public NewClient(Socket s) {
this.socket = s;
this.id = ++uniqueID;
try{
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
sdf = new SimpleDateFormat("HH:mm:ss");
}catch(Exception e) {
System.out.println("Exception while creating input/output streams: " + e);
}
}
我有一个可以正常工作的简单客户端-服务器应用程序。问题是它只适用于一个启动的客户端,但不适用于两个或更多。它建立连接,但是当您尝试在第一或第二输入文本时,服务器会中断。我认为问题可能出在 Server.java
.
broadcast()
Server.java
public class Server {
final int PORT = 5000;
private ArrayList<NewClient> al = new ArrayList<NewClient>();
private Scanner in;
private PrintWriter out;
private SimpleDateFormat sdf;
private int uniqueID = 0;
private void go(){
try{
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Waiting for clients...");
while(true) {
Socket s = serverSocket.accept();
NewClient chat = new NewClient(s);
System.out.println("Client number " + chat.getId() + " connected from: " + s.getLocalAddress().getHostName());
al.add(chat);
Thread t = new Thread(chat);
t.start();
}
}catch (Exception e) {
System.out.println("Problem with establishing network connection: ");
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.go();
}
class NewClient implements Runnable{
private Socket socket;
private int id;
public NewClient(Socket s) {
this.socket = s;
this.id = ++uniqueID;
}
public int getId() {
return this.id;
}
@Override
public void run() {
try{
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
sdf = new SimpleDateFormat("HH:mm:ss");
while(true) {
String input = in.nextLine();
System.out.println("Client said: " + input);
broadcast(input);
}
}catch (Exception e) {
e.printStackTrace();
}
}
private void writeMsg(String input) {
String msg = input + " on " + sdf.format(new Date());
out.println("You said: " + msg);
out.flush();
}
private void broadcast(String input) {
for (int i = 0; i < al.size(); i++) {
NewClient t = al.get(i);
t.writeMsg(input);
}
}
}
}
Client.java:
public class Client {
final int PORT = 5000;
final String HOST = "127.0.0.1";
private Scanner stdIn;
private Scanner in;
private PrintWriter out;
private void go() {
setUpNetwork();
}
private void setUpNetwork(){
try{
Socket s = new Socket(HOST, PORT);
System.out.println("You are connected to " + HOST);
NewClient client = new NewClient(s);
Thread t = new Thread(client);
t.start();
} catch (Exception e) {
System.out.println("Problem with connection to server: " + e);
}
}
public static void main(String[] args) {
Client client = new Client();
client.go();
}
class NewClient implements Runnable {
private Socket socket;
public NewClient(Socket s) {
this.socket = s;
}
@Override
public void run() {
try {
stdIn = new Scanner(System.in);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
while(true) {
System.out.print("> ");
String input = stdIn.nextLine();
out.println(input);
out.flush();
if(in.hasNext()) {
System.out.println(in.nextLine());
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
当打开两个Client.java并连接到server.java时一切正常。但是当我尝试从这两个打开的客户端服务器 returns 发送一些消息时,这些错误:
java.lang.IndexOutOfBoundsException: end
at java.util.regex.Matcher.region(Matcher.java:1038)
at java.util.Scanner.findPatternInBuffer(Scanner.java:1010)
Client said: sds
at java.util.Scanner.findWithinHorizon(Scanner.java:1679)
at java.util.Scanner.nextLine(Scanner.java:1538)
at Server$NewClient.run(Server.java:66)
at java.lang.Thread.run(Thread.java:745)
发生的事情是您的代码从客户端扫描第一行("sds",打印到标准输出),然后循环返回并立即尝试从客户端扫描下一行。由于客户端还没有发送任何东西,输入流扫描器抛出异常。
NewClient class 是一个内部 class。此 class 的所有实例都是使用外部 class 的相同实例创建的。更改代码将解决问题:
public NewClient(Socket s) {
this.socket = s;
this.id = ++uniqueID;
try{
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
sdf = new SimpleDateFormat("HH:mm:ss");
}catch(Exception e) {
System.out.println("Exception while creating input/output streams: " + e);
}
}