有关客户端与服务器端通信的问题

写了一段服务器端和客户端通信代码,实现以下功能:客户端将文件发送到服务器端,服务器端接收完文件后给客户端发送一个消息。
运行代码后出现以下问题不知如何神马原因:
客户端文件可以正确地传到服务器端,但是服务器端接收完文件后发送给客户端地确认消息,客户端收不到,报java.net.SocketException: Socket is closed的异常,请各位帮忙看看

客户端代码
package client;

import java.io.*;
import java.net.*;

public class ClientThread extends Thread{
private int hostPort=3000;
protected BufferedReader socketReader;
protected PrintWriter socketWriter;
private BufferedReader streamReader;

public ClientThread(){
    setUpConnection();

}

public void setUpConnection() 
{ 
try 
{ 

    Socket client = new Socket("127.0.0.1", hostPort); 
    //socketWriter = new PrintWriter(client.getOutputStream());
    InputStream inputFromSocket = client.getInputStream();
    streamReader = new BufferedReader(
            new InputStreamReader(inputFromSocket));
    handleConnection(client);
} catch (UnknownHostException e) { 
System.out.println("Error setting up socket connection: unknown host"); 
} catch (IOException e) { 
System.out.println("Error setting up socket connection: " + e); 
} 
} 



public void handleConnection(Socket client) {
    try {
        File file=new File("a.txt");
        FileReader fileReader = new FileReader(new File("a.txt"));
        BufferedReader bufferedFileReader = new BufferedReader(fileReader);
        PrintWriter streamWriter = new PrintWriter(
                client.getOutputStream());
        String line = null;
        while ((line = bufferedFileReader.readLine()) != null) {
            streamWriter.println(line);
        }
        fileReader.close();
        streamWriter.close();

        //////读取服务器收到文件后的返回内容
        String str=streamReader.readLine();
        while(str!=null){
            System.out.println(str);
        }


    } catch (Exception e) {
        System.out.println("Error handling a client: " + e);
    }
    } 

}

服务器端代码

import java.net.*;
import java.io.*;

public class ServerThread extends Thread{
private int listenPort = 3000;

public ServerThread(){
    acceptConnections();
}

public void acceptConnections() {
    try {
        ServerSocket server = new ServerSocket(listenPort);
        Socket incomingConnection = null;
        while (true) {
            incomingConnection = server.accept();
            handleConnection(incomingConnection);
        }
    } catch (BindException e) {
        System.out.println("Unable to bind to port " + listenPort);
    } catch (IOException e) {
        System.out.println("Unable to instantiate a ServerSocket on port: "
                + listenPort);
    }
}

public void handleConnection(Socket incomingConnection) {
    try {
        BufferedReader  socketReader = new BufferedReader( 
                new InputStreamReader(incomingConnection.getInputStream())); 

        String line = null;
        while ((line = socketReader.readLine()) != null) {
            //streamWriter.println(line);
            System.out.println(line);
        }
        socketReader.close();

        /////////接受完服务器发送的文件后给客户端
        OutputStream os=incomingConnection.getOutputStream();
        os.write("".getBytes());
    } catch (Exception e) {
        System.out.println("Error handling a client: " + e);
    }
}

}

给你修改了一下,可以正常运行:
[code="java"]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerThread extends Thread {
private int listenPort = 30000;

public ServerThread() {
    acceptConnections();
}

public void acceptConnections() {
    try {
        ServerSocket server = new ServerSocket(listenPort);
        Socket incomingConnection = null;
        int i=1;
        while (true) {
            System.out.println("i= " + (i++));
            incomingConnection = server.accept();
            handleConnection(incomingConnection);
        }
    } catch (BindException e) {
        System.out.println("Unable to bind to port " + listenPort);
        e.printStackTrace();
    } catch (IOException e) {
        System.out.println("Unable to instantiate a ServerSocket on port: "
                + listenPort);
    }
}

public void handleConnection(Socket incomingConnection) {
    try {
        BufferedReader socketReader = new BufferedReader(
                new InputStreamReader(incomingConnection.getInputStream()));

        String line = null;
        while (!(line = socketReader.readLine()).equals("xxx")) {
            // streamWriter.println(line);
            System.out.println(line);
        }

// socketReader.close();

        // ///////接受完服务器发送的文件后给客户端
        OutputStream os = incomingConnection.getOutputStream();
        os.write("message arrivered\n".getBytes());
        os.write("\n".getBytes());
        os.flush();
        System.out.println("handleConnection() is over");
    } catch (Exception e) {
        System.out.println("Error handling a client: " + e);
    }
}

public static void main(String[] args) {
    new ServerThread().start();
}

}
[/code]

[code="java"]
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientThread extends Thread{
private int hostPort = 30000;
protected BufferedReader socketReader;
protected PrintWriter socketWriter;
private BufferedReader streamReader;

public ClientThread() {
    setUpConnection();
}

public void setUpConnection() {
    try {

        Socket client = new Socket("127.0.0.1", hostPort);
        // socketWriter = new PrintWriter(client.getOutputStream());
        InputStream inputFromSocket = client.getInputStream();
        streamReader = new BufferedReader(new InputStreamReader(
                inputFromSocket));
        handleConnection(client);
    } catch (UnknownHostException e) {
        System.out
                .println("Error setting up socket connection: unknown host");
    } catch (IOException e) {
        System.out.println("Error setting up socket connection: " + e);
    }
}

public void handleConnection(Socket client) {
    try {
        File file = new File("src/test.txt");
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedFileReader = new BufferedReader(fileReader);
        PrintWriter streamWriter = new PrintWriter(client.getOutputStream());
        String line = null;
        while ((line = bufferedFileReader.readLine()) != null) {
            streamWriter.println(line);
        }
        streamWriter.println("xxx");
        streamWriter.flush();
        fileReader.close();
        // 此处不能断,否则就断开了与服务器的 socket 连接
        // streamWriter.close();
        // ////读取服务器收到文件后的返回内容
        String str;
        while ((str = streamReader.readLine()) != null && !str.equals("")) {
            System.out.println(str);
        }
        System.out.println("client thread is over");
    } catch (Exception e) {
        System.out.println("Error handling a client: " + e);
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    new ClientThread().start();
}

}
[/code]

[quote]java.net.SocketException: Socket is closed[/quote]
是哪一行报的错啊?

初步推测:
[quote]
//////读取服务器收到文件后的返回内容
String str=streamReader.readLine();
while(str!=null){
System.out.println(str);
}
[/quote]
这个操作在服务器返回有效结果前已经被执行过,导致客户端的 Thread 的线程执行完毕,从而断开发与服务器的连接(从而可能导致服务器还没有把文件接收结束就已经报了这个异常)。你可以在上面的操作之前加个
[code="java"]
Thread.sleep(2000);
[/code]
来模拟一下服务器返回结果的延迟效果,看看还能不能收到结果

那把
Thread.sleep(2000);

的时间设置成更大一点。
另外,你的 客户端 与 服务端 是分开启动的吧?

[quote]streamWriter.close();[/quote]
关键是你上面这句代码的问题,通过源码可以看出
[code="java"]
public void close() {
try {
synchronized (lock) {
if (out == null)
return;
out.close();
out = null;
}
}
catch (IOException x) {
trouble = true;
}
}
[/code]
会把 out 关闭且置为 null,那么 out 是什么呢?
[quote]PrintWriter streamWriter = new PrintWriter(client.getOutputStream());[/quote]
上面是你的代码。去看一下 PrintWriter 的源码便知:
[code="java"]
public PrintWriter(OutputStream out) {
this(out, false);
}
[/code]
[code="java"]
public PrintWriter(OutputStream out, boolean autoFlush) {
this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);

// save print stream for error propagation
if (out instanceof java.io.PrintStream) { 
    psOut = (PrintStream) out;
}
}

[/code]
[code="java"]
public PrintWriter(Writer out,
boolean autoFlush) {
super(out);
this.out = out;
this.autoFlush = autoFlush;
lineSeparator = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
}
[/code]
可见,这个 out 就是你通过 socket 得到的 getOutputStream,那么怎么才能将这个 getOutputStream 关闭呢,当然就是断开这个 socket 啦,所以,你会一直得到这个异常

另外判断一个文件是否读完,不能通过是否读取到了 null 来判断,而是应该使用特地的结束符来判断