问题是,我按照一般写法,所有输入流,输出流在操作完毕后,就直接给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)请各位不吝赐教,先谢谢了
服务端代码:
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)请各位不吝赐教,先谢谢了
我把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客户端无异常
this.socket.close();
}
问题是this.socket.getOutputStream().close();
总是失败的
服务器端应该是不需要关闭的,服务器端应该开启一个端口一直监听。当客服端有请求过来就处理掉并返回,client端在完成请求并接受到信息之后应该关闭·
,当然一次处理完成后服务端也关,是比较好的
我用的是短连接,发送一次报文,就重建一次连接的