这个单线程echo服务器工作正常。
public class Server {
public static void main(String[] args) throws IOException {
try (ServerSocket sc = new ServerSocket(1111)) {
while (true) {
try (Socket dataSocket = sc.accept();
BufferedReader is = new BufferedReader(
new InputStreamReader(
dataSocket.getInputStream()));
PrintWriter out = new PrintWriter(
dataSocket.getOutputStream());) {
String line;
while ((line = is.readLine()) != null) {
System.out.println(line);
out.println(line);
out.flush();
if (line.equals("Bye."))
break;
}
}
}
}
}
}
但为什么这个多线程版本不起作用?它只是传递输入和输出流来构造TestServer1线程并启动它。没什么特别的。但不知何故,当客户端连接到此服务器时,"Stream close"
中会抛出run()
异常并打印"error in run"
。
public class TestServer1 extends Thread{
BufferedReader in;
PrintWriter out;
public TestServer1(BufferedReader in, PrintWriter out){
this.in=in;
this.out=out;
}
@Override
public void run(){
String line;
try{
while ((line = in.readLine()) != null) {
System.out.println(line);
out.println(line);
out.flush();
if (line.equals("Bye."))
break;
}
} catch (IOException e){
System.out.println("error in run");
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
try (ServerSocket sc = new ServerSocket(1111)) {
while (true) {
try (Socket dataSocket = sc.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(
dataSocket.getInputStream()));
PrintWriter out = new PrintWriter(
dataSocket.getOutputStream());) {
TestServer1 ts1=new TestServer1(in, out);
ts1.start();
}
}
}
}
}
这是stacktrace
error in run
java.io.IOException: Stream closed
at java.io.BufferedReader.ensureOpen(BufferedReader.java:115)
at java.io.BufferedReader.readLine(BufferedReader.java:310)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at server.TestServer1.run(TestServer1.java:22)
答案 0 :(得分:1)
Java 7:尝试使用资源
使用Java 7,您可以在try中创建一个或多个“资源” 声明。 “资源”是实现这一目标的东西 java.lang.AutoCloseable接口。这个资源就是 自动关闭并尝试阻止结束。
来自javadocs:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
在此示例中,try-with-resources语句中声明的资源是BufferedReader。声明语句出现在try关键字后面的括号内。 Java SE 7及更高版本中的BufferedReader类实现了java.lang.AutoCloseable接口。因为BufferedReader实例是在try-with-resource语句中声明的,所以无论try语句是正常还是突然完成(由于BufferedReader方法的结果),它都将被关闭。
链接:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
所以可能这可能是理由,当你的视频超出范围时你的视频会自动关闭。
答案 1 :(得分:0)
try()就是原因。 try(.....)块后将关闭流。 请测试此代码:
while (true) {
try {
Socket dataSocket = sc.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(
dataSocket.getInputStream()));
PrintWriter out = new PrintWriter(
dataSocket.getOutputStream());
TestServer1 ts1 = new TestServer1 (in, out);
ts1.start();
} catch (Exception e) {
e.printStackTrace();
}
}
P.S:你需要在线程run()方法中关闭流。
答案 2 :(得分:0)
请尝试以下版本 - 未经测试。但正如我在评论中所说,我相信你在TryWithResources中提前关闭了输出流
public class TestServer1 extends Thread{
Socket connection;
public TestServer1(Socket connection){
this.connection = connection;
}
@Override
public void run(){
try (BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
PrintWriter out = new PrintWriter(connection.getOutputStream());) {
String line;
try {
while ((line = in.readLine()) != null) {
System.out.println(line);
out.println(line);
out.flush();
if (line.equals("Bye."))
break;
} catch (IOException e){
System.out.print("error in run");
}
}
}
public static void main(String[] args) throws IOException {
try (ServerSocket sc = new ServerSocket(1111)) {
while (true) {
try (Socket dataSocket = sc.accept()) {
TestServer1 ts1=new TestServer1(dataSocket);
ts1.start();
}
}
}
}
}
答案 3 :(得分:0)
基于@Amir,@ LFF和@Abhijeet的答案,我把以下版本放在一起,它的确有效。主要的收获是:“Socket dataSocket = sc.accept()”不应该作为资源放入“try()”;否则,主线程将关闭它。它应该由“run()”中的子线程关闭。
谢谢大家的帮助。
public class ThreadedServer extends Thread {
private Socket dataSocket;
public ThreadedServer(Socket dataSocket) throws IOException {
this.dataSocket = dataSocket;
}
@Override
public void run() {
String line;
try (BufferedReader in = new BufferedReader(new InputStreamReader(
dataSocket.getInputStream()));
PrintWriter out = new PrintWriter(dataSocket.getOutputStream());) {
while ((line = in.readLine()) != null) {
System.out.println(line);
out.println(line);
out.flush();
if (line.equals("Bye."))
break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
dataSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
try (ServerSocket sc = new ServerSocket(1111)) {
while (true) {
try {
Socket dataSocket = sc.accept();
ThreadedServer ts = new ThreadedServer(dataSocket);
ts.start();
} finally {
}
}
}
}