问题是,我按照一般写法,所有输入流,输出流在操作完毕后,就直接给close了,但是就会报错。如果不都给close掉,程序还正常的
服务端代码:
public class Server2 extends Thread {
Socket socket;
public Server2(Socket socket, String uuid) {
super(uuid);
this.socket = socket;
}
@Override
public void run() {
System.out.println("running..");
try {
this.readSocket();
this.writeSocket();
} catch (Exception ioe) {
ioe.printStackTrace();
} finally {
this.closeSocket();
}
}
/**
 * 将response信息发送到socket客户端
 * 
 * @param response
 */
private void readSocket() {
try {
InputStream ins = socket.getInputStream();
DataInputStream dins = new DataInputStream(ins);
byte[] size = new byte[10];
dins.read(size);
System.out.println("size is "+new String(size));
byte[] xml = new byte[Integer.parseInt(new String(size))];
dins.readFully(xml);
System.out.println("xml is "+new String(xml));
ins.close();
dins.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
 * 将response信息发送到socket客户端
 * 
 * @param response
 */
private void writeSocket() {
try {
OutputStream outs = socket.getOutputStream();
DataOutputStream douts = new DataOutputStream(outs);
byte[] b = this.compress();
DecimalFormat format=new DecimalFormat("0000000000");   
String size = format.format(b.length);
douts.write(size.getBytes());
douts.write(b);
douts.flush();
douts.close();
outs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private byte[] compress() {
String xml = "<aa><bb>测试xml</bb></aa>";
return GZip.compress(xml.getBytes());
}

/**
 * 一个线程处理完后,关闭socket连接
 */
public void closeSocket() {
try {
this.socket.close();
} catch (IOException e) {
System.out.println("关闭socket异常");
e.printStackTrace();
}
} public static void main(String args[]) {
ExecutorService exService = Executors.newFixedThreadPool(30);
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(9999);
System.out.println("服务成功启动了!");
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
Socket socket = serverSocket.accept();
socket.setSoLinger(true, 3600); //未发送完全的数据可以再等3600秒才关闭底层socket    
System.out.println("接收到一个客户端请求!");
UUID uuid = UUID.randomUUID();
Server2 sp = new Server2(socket, uuid.toString());
exService.execute(sp);
//sp.start();
//sp.join();// 主线程要等待该线程终止。
} catch (Exception ne) {
ne.printStackTrace();
}
}
}
}
客户端代码public class SocketClient2 extends Thread {
static int count=0;
@Override
public void run() {
try {
byte[] ww = "<root></root>".getBytes();
Socket socket = new Socket("localhost",9999);
socket.setSoTimeout(2*60*1000);
OutputStream outs = socket.getOutputStream();
DecimalFormat format=new DecimalFormat("0000000000");   
String size = format.format(ww.length);
//用来通知长度的报文头
outs.write(size.getBytes());
//报文内容
outs.write(ww);
//刷新缓冲区
outs.flush();
outs.close();

InputStream ins = socket.getInputStream();
DataInputStream dins = new DataInputStream(ins);
byte[] aa = new byte[10];
//读取报文头,以获得报文内容的长度
dins.readFully(aa);
String rsize = new String(aa);
//获取报文内容
byte[] cc = new byte[Integer.parseInt(rsize)];
dins.readFully(cc);
System.out.println(new String(cc));
byte[] xx = GZip.decompress(cc);
System.out.println(new String(xx));
dins.close();
ins.close();
//cc();
    
} catch(Exception e) {
e.printStackTrace();
}

}
  public static void main(String args[]) throws Exception {
for (int i=0;i<1;i++) {
SocketClient2 t = new SocketClient2();
t.start();
}

}
}先启动服务程序,再启动客户端程序,
服务端异常如下
服务成功启动了!
接收到一个客户端请求!
running..
size is 0000000013
xml is <root></root>
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Unknown Source)
at socket.Server2.writeSocket(Server2.java:69)
at socket.Server2.run(Server2.java:32)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)客户端异常如下
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Unknown Source)
at socket.SocketClient2.run(SocketClient2.java:34)请各位不吝赐教,先谢谢了

解决方案 »

  1.   

    是有点长,但是这是一个socket程序必须的,我觉得。
      

  2.   

    java.net.SocketException: Socket is closed异常提示Socket已经关闭了 应该是先关闭客户端Socket 再关服务器的
      

  3.   

    如何做到先关客户端的,再关服务器的,他们2个是通过socket通信的,是两个独立的运行的程序。
    我把close方法改了下:/**
     * 一个线程处理完后,关闭socket连接
     */
    public void closeSocket() {
    try {
    this.socket.getInputStream().close();
    System.out.println("close InputStream success");
    } catch (IOException e) {
    System.out.println("关闭InputStream异常");
    e.printStackTrace();
    }
    try {
    this.socket.getOutputStream().close();
    System.out.println("close OutputStream success");
    } catch (IOException e) {
    System.out.println("关闭OutputStream异常");
    e.printStackTrace();
    }
    try {
    this.socket.close();
    System.out.println("close socket success");
    } catch (IOException e) {
    System.out.println("关闭socket异常");
    e.printStackTrace();
    }
    }服务端异常如下
    close InputStream success
    关闭OutputStream异常
    java.net.SocketException: Socket is closed
    at java.net.Socket.getOutputStream(Unknown Source)
    at socket.Server2.closeSocket(Server2.java:100)
    at socket.Server2.run(Server2.java:36)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    close socket success客户端无异常
      

  4.   

    (!this.socket.isClosed()){
     this.socket.close();
    }
      

  5.   

    最近我也再看socket编程 关注下
      

  6.   

     this.socket.close(); 这句总是执行成功的,
    问题是this.socket.getOutputStream().close();
    总是失败的
      

  7.   

    客户端没有关闭·
    服务器端应该是不需要关闭的,服务器端应该开启一个端口一直监听。当客服端有请求过来就处理掉并返回,client端在完成请求并接受到信息之后应该关闭·
      

  8.   

    socket连接不要每次都关闭流,只在最后退出时关闭
      

  9.   

    谢谢各位了,客户端确实需要关闭SOCKET
    ,当然一次处理完成后服务端也关,是比较好的
    我用的是短连接,发送一次报文,就重建一次连接的
      

  10.   

    想了解多线程的socket和输入输出流怎么关闭的
      

  11.   

    socket.shutdownOutput();// 关闭socket对象的输出流
      

  12.   

    使用close关闭输入输出流 socket直接关闭 并且输入输出流不可以重复使用