服务器端代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
public class SocketRecvThread extends Thread { Socket socket;
public SocketRecvThread(Socket s){
this.socket = s;
}
public void run() {
InputStream is = null;
//读取客服端的输入输出流
BufferedInputStream bis = null;
DataInputStream dis = null;
System.out.println("run");
try {
is = socket.getInputStream();
bis = new BufferedInputStream(is);
dis = new DataInputStream(bis);
} catch (IOException e) {
e.printStackTrace();
}
//向客户端发送密码是否成功的输入输出流
OutputStream os = null;
BufferedOutputStream bos = null;
DataOutputStream dos = null;
try {
os = socket.getOutputStream();
} catch (IOException e3) {
e3.printStackTrace();
}
bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);

//判断账号密码是否正确
String userMessage = null;
System.out.println("userma");
try {
userMessage = dis.readUTF();
} catch (IOException e2) {
e2.printStackTrace();
}
                  //为了方便,假设为正确的
String userName = "zhangsan";
String password = "zhangsan";
System.out.println("客户端账号密码为:" + userMessage);
if(userName.equals("zhangsan")&&password.equals("zhangsan")){
try {
System.out.println("服务器用户信息验证正确");
dos.writeUTF("true");
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
//账号密码正确关闭向客户端发送信息的流
try {
dos.close();
bos.close();
os.close();
} catch (IOException e2) {
e2.printStackTrace();
}
//读取客户端文件格式
String ext = null;
try {
System.out.println("读取文件格式");
ext = dis.readUTF();
System.out.println(ext);
} catch (IOException e1) {
e1.printStackTrace();
}
//服务器端所存文件位置以及名字
File file = new File("E:\\apache-tomcat-5.5.27\\webapps\\my_graduation\\upload\\video\\"
+ Long.toString(new Date().getTime()) + "." + ext);
FileOutputStream fis = null;
BufferedOutputStream bos1 = null;
//写入服务器文件的文件流
try {
fis = new FileOutputStream(file);
bos1 = new BufferedOutputStream(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//向服务器文件写入数据
byte [] buffer = new byte[10240];
int i = -1;
try {
while((i = dis.read(buffer)) > 0){
bos1.write(buffer,0,i);
bos1.flush();
}
System.out.println("文件传输完毕");
} catch (IOException e1) {
e1.printStackTrace();
}
try {
bos1.close();
fis.close();
dis.close();
bis.close();
is.close();
System.out.println("客户端关闭");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
dos.writeUTF("false");
} catch (IOException e) {
e.printStackTrace();
}
try {
dos.close();
bos.close();
os.close();
dis.close();
bis.close();
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端代码大概
用户验证一个类 witerUTF();1次
readUTF();1次 读取用户验证是否正确
正确则执行另一个类 witerUTF();1次,将所传文件扩展名发到服务器端(这个类的网络流是验证的类传过来的)
                   witer()N次,知道把文件传完
偶尔抛出java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at cn.edu.syict.tcp.client.LoginActionListener.actionPerformed(LoginActionListener.java:83)
这个是readUTF()那个位置
at java.awt.Button.processActionEvent(Unknown Source)
at java.awt.Button.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
服务器端
readUTF();能够接受到用户信息
第2次readUTF();
抛出java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at cn.edu.syict.tcp.server.SocketRecvThread.run(SocketRecvThread.java:81)请问这么解决?
网络流readUTF没读到是等待,还是抛异常了继续执行
普通的read()是没读到等待还是不符合条件跳出继续执行
(如果网速很慢的话,客户端还没发完,而服务器端read()没读到是不是就跳出了?)

解决方案 »

  1.   

    在服务端/客户端单方面关闭连接的情况下,另一方依然以为
    tcp连接仍然建立,试图读取对方的响应数据,导致出现
    Software caused connection abort: recv failed的异常. 
    http://www.javaeye.com/topic/253123java.net.SocketException: socket closed
    这个很清楚了,socket 关闭了
      

  2.   

    我知道已经关闭了,你说说下面问题啊
    网络流readUTF没读到是等待,还是抛异常了继续执行 
    普通的read()是没读到等待还是不符合条件跳出继续执行 
    (如果网速很慢的话,客户端还没发完,而服务器端read()没读到是不是就跳出了?)
      

  3.   

    写完文件用
    Thread.sleep(2000);
    再试下
      

  4.   

    怎么都喜欢用缓冲流去读socket的...谁教你的...
    缓冲流只适合用来读写本地字符数据,并不适合用来读写socket流
    一般读流这么读
    InputStream is = 一个输入流;
    byte[] buf = new byte[1024];
    int readSize = 0;
    int count = 100; // 假设数据包大小为100,一般情况下应采用包头包体结构,从包头读取数据包大小
    while((readSize += inputStream.read(bHead,readSize,count-readSize)) != -1 && readSize < count) {}
    if(readSize == -1) 
    throw new SocketException("连接断开");// 处理接收的byte数组
    doSomething(buf);
      

  5.   

    中属于tcp上的socket关闭问题,可能是连接过早被你关闭掉了,比如io中的flash()、close()、或者socket中timeout值设置过小,linger设置小都会出这问题
      

  6.   

    谢谢各位回答,我已经弄出来了。try {
                    dos.close();
                    bos.close();
                    os.close();
                } catch (IOException e2) {
                    e2.printStackTrace();
                }
    这个关闭 socket也关闭了