以下是服务器的代码
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)
但我真的找不到这个bug。请给我一个提示。
答案 0 :(得分:1)
在循环的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();
}
}
答案 1 :(得分:0)
您不应该在循环内关闭serverSocket。将while循环放在try块中。
答案 2 :(得分:0)
启动服务器程序时,它会在此行上阻止:
socket = sSocket.accept();
然后启动客户端程序,将immediatley连接到服务器(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
,然后在同一个关闭的套接字上尝试accept,因此异常。如果您重写代码如下:
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();
然后启动客户端,输入您想要的内容并按回车键,返回服务器并跳过,您将看到(仅)传输的第一条消息 - 看起来您不希望它表现得那样,但这是另一个问题。
我强烈建议您仔细阅读认真官方Java socket tutorial。