我本来是用socket做服务器和客户的文件传输。发现有问题后 就用两个线程模拟这个过程,结果发现仍然有问题。我每次都用了如下代码
客户:send_file=new FileInputStream(file);
output=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while((read_length=send_file.read(file_byte))!=-1){
output.write(read_length+"\n");
output.flush();
}
服务器则每次都先检测下次要接收的长度,然后再接受while((length=Integer.parseInt(reader.readLine()))!=-1)按理说应该没问题,结果总是出现reader.realLine()读到的并不是一个数,而是字符串我想是不是因为双线程同时跑,他把读取顺序搞错了,于是加上了等待语句,程序变成这样:
while(长度!=-1){
客户:  发送下次的文件长度
服务器:接收文件长度,告知客户开始上传该部分文件
客户:  发送一定长度的文件
服务器:接收文件内容,告知客户开始上传下次的文件长度
}
这个程序有时出错(小文件一般不错,一般第一次开机,传大文件也不会错。。但是传成功一次文件后,再传大文件就会出错。很诡异)
程序代码如下,其中有个地方是传输的文件地址,测试时可以修改,建议传rmvb,最容易出错。
import java.awt.FlowLayout;
import java.io.*;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PipedWriter;
import java.net.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class thread {
String s=null;
/**
 * @param args
 * @throws InterruptedException 
 * @throws IOException 
 */
public static void main(String[] args) throws InterruptedException, IOException {
thread test=new thread();
test.Go();

}

private void Go() throws IOException {
ServerSocket  sever=new ServerSocket(8080);
Socket clicent=new Socket(InetAddress.getByName("localhost"),8080);
Socket sev=sever.accept();
FileSocket seve_file=new FileSocket(sev);
file_trans one_file=new file_trans(new File("F:/huxiDownloads/新三国51.rmvb"),clicent,seve_file.responpiped);
one_file.start();
seve_file.start();
sever.close();

} public class FileSocket extends Thread{
Socket socket=null;
BufferedInputStream reader_file=null;
FileOutputStream file_w=null;
String file_name=null;
BufferedWriter respon=null;
BufferedReader reader=null;
public PipedWriter responpiped;
FileSocket(Socket getSocket) {
this.socket=getSocket;
responpiped=new PipedWriter();
}
public void run(){
System.out.println("服务器"+this.getName()+"进入接收文件状态\n");//-----------------------------------------

try {
reader_file = new BufferedInputStream(socket.getInputStream());
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
respon=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); file_name=reader.readLine();
System.out.println("服务器"+this.getName()+"读到文件名:"+file_name+"\n");//-----------------------------------------
file_w=new FileOutputStream(new File(file_name));
byte[] file_rw=new byte[8192];
int length;
String temp;
//回馈
respon.write("Bgein\n");respon.flush();
//responpiped.write('b');
System.out.println("服务器"+this.getName()+"告知客户已得到文件名,可以开始上传");
while((length=Integer.parseInt(reader.readLine()))!=-1){
System.out.println("服务器"+this.getName()+"将要接收的字符长度:"+length);
System.out.println("服务器"+this.getName()+"告知客户已得到数据长度,可以继续");

//回馈
//responpiped.write('c');
respon.write("give me content\n");respon.flush();

reader_file.read(file_rw, 0, length);
System.out.println("服务器"+this.getName()+"读到字符byte数组");
file_w.write(file_rw, 0, length);
file_w.flush();
System.out.println("服务器"+this.getName()+"写入到文件部分内容"); System.out.println("服务器"+this.getName()+"告知客户已得到数据内容,可以继续\n");
//responpiped.write('n');
//回馈
respon.write("give me length\n");respon.flush();

} } catch (IOException e) {
e.printStackTrace();
}finally{
try {
file_w.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}
}


public class file_trans extends Thread{
Socket socket=null;
File file=null;
BufferedWriter output=null;
BufferedOutputStream output_file=null;
BufferedReader input=null;
PipedReader getrespon=null;
file_trans(File myfile,Socket so,PipedWriter pip) throws IOException{
socket=so;
file=myfile;
getrespon=new PipedReader(pip);
try {
output=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
input=new BufferedReader(new InputStreamReader(socket.getInputStream()));
output_file=new BufferedOutputStream(socket.getOutputStream());
} catch (IOException e) { e.printStackTrace();
}
}
public void run(){
byte[] file_byte=new byte[8192];
    int read_length;
    FileInputStream send_file=null;
     try {
send_file=new FileInputStream(file);
output.write(file.getName()+"\n");
output.flush();
System.out.println("窗体发送文件名:"+file.getName());//-----------------------------------------
//等待
System.out.println(input.readLine());
//System.out.println((char)getrespon.read());
System.out.println("窗体"+this.getName()+"接收服务器命令,开始传送");//-----------------------------------------
while((read_length=send_file.read(file_byte))!=-1){
output.write(read_length+"\n");
output.flush();
System.out.println("窗体"+this.getName()+"发送本次文件读入大小:"+read_length);//-----------------------------------------
//等待
System.out.println(input.readLine());//询问服务器是否收到信息,起到强行等待的作用,否则由于多线程,会不停传输数据
//System.out.println((char)getrespon.read());
System.out.println("窗体"+this.getName()+"接收服务器续传命令");//-----------------------------------------
output_file.write(file_byte, 0, read_length);
output_file.flush();
System.out.println("窗体"+this.getName()+"发送部分byte");
//等待
System.out.println(input.readLine());//询问服务器是否收到信息,起到强行等待的作用,否则由于多线程,会不停传输数据
//System.out.println((char)getrespon.read());
System.out.println("窗体"+this.getName()+"接收服务器续传命令");
}
//input.readLine();//询问服务器是否收到信息,起到强行等待的作用,否则由于多线程,会不停传输数据
//System.out.println("窗体"+this.getName()+"接收服务器续传命令");
output.write("-1\n");
output.flush();
System.out.println("窗体"+this.getName()+"发送结束文件传输口令\n");
//send_file.close();

    
    } catch (FileNotFoundException e1) {
System.out.println("找不到文件");
e1.printStackTrace();
} catch (IOException e2) {
System.out.println("文件无法读取");
// TODO Auto-generated catch block
e2.printStackTrace();
}finally{
try {
send_file.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}}
关于强行回馈 我是用的socket的流互相读。后来我怕是这个问题,改成了piped线程通信流作为客户服务之间的响应,这么一来很慢,但是还是出错。
piped的调试代码均是注释内容(就是说我提供了两种回馈形式,piped更利于调试,因为他把线程运行顺序控制的很死)
到底哪里错了= =求助

解决方案 »

  1.   

    while((length=Integer.parseInt(reader.readLine()))!=-1)是有问题的!String str = null;
    while((str = reader.readLine()))!=null)应该这么写否则Integer.parseInt(null)是要抛异常的
      

  2.   

    但是测试结果就是  读取一段后,这个length=Integer.parseInt(reader.readLine()) 读取到的就不再是数字字符串了  
    可是我的程序逻辑明明保证了他读到的一定是数字字符串。
      

  3.   

    reader.readLine()一次读一行,我没看你整个逻辑,单就这个做些讨论也就是说,如果文件中某一行只有“-1”这两个字符串,你的while循环就终止了,下面还有内容也不会再去读了
      

  4.   


    服务器上我是用了两个流做读入,一个是InputStream 一个是BufferedReader
    读取长度时候采用readLine(),读取内容的时候用的是InputStream的read(byte[],0,length)...所以 如果reader.readLine()读到-1 那一定就是完了。。