Вот коды, я думаю, что они все в порядке, однако JRE так не считает
Вот коды сервера
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.IOException;
public class MyServer {
private int port;
private ServerSocket sSocket = null;
public MyServer(int port) throws IOException {
this.port = port;
sSocket = new ServerSocket(port);
}
public MyServer() throws IOException {
this(10005);
}
public void serve() {
Socket socket = null;
while (true) {
try {
socket = sSocket.accept();
new MyThread(socket).start();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (sSocket != null) sSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException {
new MyServer().serve();
}
}
class MyThread extends Thread {
Socket socket;
public MyThread(Socket s) {
socket = s;
}
public void run() {
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
String msg = null;
while((msg = reader.readLine()) != null) {
System.out.print("Get:\t" + msg + "\nSending back...");
writer.println("Echo" + msg);
System.out.println("done.");
if (msg.equals("bye")) break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socket != null) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Вот коды клиента.
import java.net.Socket;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedReader;
public class MyClient {
private int port;
private Socket socket;
public MyClient(String host, int port) throws IOException {
socket = new Socket(host, port);
}
public MyClient(int port) throws IOException {
this("localhost", port);
}
public MyClient() throws IOException {
this("localhost", 10005);
}
public void talk() {
try {
BufferedReader localReader = new BufferedReader(
new InputStreamReader(System.in));
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
String msg = null;
while((msg = localReader.readLine()) != null) {
writer.println(msg);
wirter.flush();
System.out.println(reader.readLine());
if (msg.equals("bye")) break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socket != null) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new MyClient().talk();
}
}
Ошибка сказала:
at MyServer.main(MyServer.java:41)
java.net.SocketException: Socket is closed
at java.net.ServerSocket.accept(Unknown Source)
at MyServer.serve(MyServer.java:26)
at MyServer.main(MyServer.java:41)
Но я действительно не могу найти ошибку. Пожалуйста, дайте мне подсказку.
3 ответа
В вашем блоке finally, который находится внутри цикла, вы закрываете сокет сервера:
try {
socket = sSocket.accept();
new MyThread(socket).start();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (sSocket != null)
sSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Измените свой код на:
try {
socket = sSocket.accept();
new MyThread(socket).start();
} catch (IOException e) {
try {
if (sSocket != null)
sSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Когда вы запускаете серверную программу, она блокируется в этой строке:
socket = sSocket.accept();
Затем вы запускаете клиентскую программу, которая сразу подключается к серверу (new MyClient()
) и блокирует ожидание пользовательского ввода с консоли:
BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
while((msg = localReader.readLine()) != null) {
Когда вы подключили клиента к серверу, сервер запустил новый поток:
new MyThread(socket).start();
который заблокировал ожидание клиентского ввода (пользовательский ввод на консоли с другой стороны сокета):
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while((msg = reader.readLine()) != null) {
Но после создания нового потока для обработки клиентского запроса ваш сервер закрывает sSocket
, а затем пытается принять в том же закрытом сокете, отсюда и исключение. Если вы переписываете свой код следующим образом:
public void serve() {
Socket socket = null;
while (true) {
try {
System.out.println("1 "+System.currentTimeMillis());
socket = sSocket.accept();
System.out.println("2 "+System.currentTimeMillis());
new MyThread(socket).start();
System.out.println("3 "+System.currentTimeMillis());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("4 "+System.currentTimeMillis());
if (sSocket != null) {
System.out.println("5 "+System.currentTimeMillis());
sSocket.close();
}
System.out.println("6 "+System.currentTimeMillis());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Вы увидите следующий вывод:
1 1370944252112
2 1370944260482
3 1370944260487
4 1370944260487
5 1370944260487
6 1370944260487
1 1370944260487
4 1370944260488
5 1370944260488
6 1370944260488
1 1370944260488
4 1370944260488
5 1370944260488
6 1370944260488
Это означает, что ваш сервер находится в бесконечном цикле, постоянно выдавая исключение. Чтобы решить проблему бесконечного цикла, смотрите ответ @ gma.
Если вы запускаете сервер в режиме отладки и ставите точку останова в этой строке:
socket = sSocket.accept();
а затем запустите клиент, введите то, что вы хотите, и нажмите Enter, вернитесь на сервер и перешагните через него, вы увидите (только) первое переданное сообщение - похоже, вы не хотели, чтобы оно так себя вели, но это другая проблема.
Я настоятельно рекомендую вам внимательно прочитать официальное руководство по сокетам Java.
Вы не должны закрывать свой serverSocket внутри цикла. Поместите цикл while в блок try.