我现在写了一个Java Socket 程序,就是服务器向客户端发送一个文件夹,可是现在写的结果出现了,就是服务器发送过去后,在客户端第一文件可以接收到,但是第二个,第三个....都为0字节,现在急死了,CSDN的的高手们,帮帮忙看看,为啥 ,然后给写解决办法,和一点点源程序,感激不尽!!! 
以下为服务器代码: 
import java.net.*; 
import java.util.Vector; 
import com.cyberwisdom.tools.*; 
import java.io.*; 
import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
import com.cyberwisdom.tools.Log; 
import com.cyberwisdom.tools.share.DataPacket; 
public class MultiFileSuport extends Thread{ private Socket sck; 
private Vector vFile;//缓存文件列表 
public MultiFileSuport(Socket sck,Vector vFile){ 
this.sck=sck; 
this.vFile=vFile; 
this.start(); 
Log.logDebug("Thread start success"); 
} public void run(){ 
ObjectOutputStream out=null; DataOutputStream dOut=null; BufferedInputStream in=null; 
byte [] buffer=new byte[1024*5]; 
try{ 
out=this.getObjectOutputStream(sck); 
out.writeObject(vFile);//发送文件列表参数,在客户端在处理路径 
out.flush(); 
                        //发送文件流 
for(int i=0;i <vFile.size();i++) 

dOut=this.getDataOutputStream(sck); File file=new File(vFile.get(i).toString()); in=new BufferedInputStream(new FileInputStream(file)); 
dOut.writeLong(file.length()); 
while(true){ 
int read=0; 
if(in!=null){ 
read=in.read(buffer); 

if(read==-1){ 
break; 

dOut.write(buffer,0,read); 


dOut.flush(); 
dOut.close(); 

catch(Exception ex){ 
Log.writeLog("","MultiFileSuport->run",ex); 
} } 
private ObjectOutputStream getObjectOutputStream(Socket sck){ 
ObjectOutputStream out=null; 
try{ 
out=new ObjectOutputStream(sck.getOutputStream()); 
}catch(IOException ex){ 
Log.writeLog("","MultiFileSuport->getObjectOutputStream",ex); 

return out; 

private DataOutputStream getDataOutputStream(Socket skc){ 
DataOutputStream out=null; 
try{ 
out=new DataOutputStream(sck.getOutputStream()); 
}catch(IOException ex){ 
Log.writeLog("","MultiFileSuport->getDataOutputStream",ex); 

return out; 

} 以下为客户端部分: import java.net.*; 
import java.io.*; 
import java.util.Vector; 
import com.cyberwisdom.tools.ReadConfig; 
import com.cyberwisdom.tools.Log; 
import com.cyberwisdom.tools.share.DataPacket; 
import com.cyberwisdom.tools.StringUtil; 
public class SocketFileClient extends Thread 
{ private ReadConfig cfg=ReadConfig.newInstance(); private boolean isStop=false; byte [] buf=new byte[1024*5]; 
private Vector vFile=new Vector(); public SocketFileClient(){ 
this.start(); 

public void run(){ 
BufferedOutputStream out=null; 
ObjectInputStream in=null; 
Socket sck=this.getSocket(); 
DataInputStream dIn=null; 
try{ 
in=this.getObjectInputStream(sck); 
vFile=(Vector)in.readObject(); 
if(!vFile.isEmpty()){ 
for(int i=0;i <vFile.size();i++){ 
String path=vFile.get(i).toString(); 
String fileName=this.getFileName(path); path=this.replace(path.substring(path.indexOf(":")+2),fileName,""); 
String sDirec=cfg.localFilePath+path; //建立文件夹 
File fDircetory=new File(sDirec); 
if(!fDircetory.exists()){ 
fDircetory.mkdirs(); 

//建立文件 
File fCreate=new File(sDirec+fileName); 
if(!fCreate.exists()){ 
fCreate.createNewFile(); 
} dIn=this.getDataInputStream(sck); 
out=new BufferedOutputStream(new FileOutputStream(fCreate)); if(dIn!=null){ 
//写入文件 
while(true){ 
int read=0; 
if(dIn!=null){ 
read=dIn.read(buf); } 
if(read==-1){ 
break; 
} out.write(buf,0,read); 

out.flush(); 

else{ 
Log.logDebug("结束一个文件"); 
continue; 

Log.logDebug(sDirec+fileName); 
Log.logDebug("成功写入文件"); 



catch(Exception ex){ 
Log.writeLog("","SocketFileClient->download",ex); 


private DataInputStream getDataInputStream(Socket sck){ 
DataInputStream in=null; 
try{ 
in=new DataInputStream(sck.getInputStream()); 

catch(IOException ex){ 
Log.writeLog("","Socket->getDataInputStream",ex); 

return in; 

private Socket getSocket(){ 
Socket sck=null; try{ 
sck=new Socket(cfg.host,cfg.port); 

catch(UnknownHostException ex){ 
Log.writeLog("","Socket->getSocket",ex); 

catch(IOException exc){ 
Log.writeLog("","Socket->getSocket",exc); 

return sck; 

private ObjectInputStream getObjectInputStream(Socket sck){ 
ObjectInputStream in=null; 
try{ 
in=new ObjectInputStream(sck.getInputStream()); 

catch(IOException ex){ 
Log.writeLog("","Socket->getObjectInputStream",ex); 

return in; 
} private String getFileName(String path){ File file=new File(path); 
return file.getName(); 

private String replace( String line, String oldString, String newString ) 
    { 
        if (line == null) { 
            return null; 
        } 
        int i=0; 
        if ( ( i=line.indexOf( oldString, i ) ) >= 0 ) { 
            char [] line2 = line.toCharArray(); 
            char [] newString2 = newString.toCharArray(); 
            int oLength = oldString.length(); 
            StringBuffer buf = new StringBuffer(line2.length); 
            buf.append(line2, 0, i).append(newString2); 
            i += oLength; 
            int j = i; 
            while( ( i=line.indexOf( oldString, i ) ) > 0 ) { 
                buf.append(line2, j, i-j).append(newString2); 
                i += oLength; 
                j = i; 
            } 
            buf.append(line2, j, line2.length - j); 
            return buf.toString(); 
        } 
        return line; 
    } 
}

解决方案 »

  1.   

    喔 ,好像是,哪么我在客户端哪边因为是一个线程?我怎么可以多次获取?Socket呢?这个问题我感觉不好着手,请兄台指点?如何做?能够写出一点点思路代码吗?程序跑通了后,我会专门写一个序列化的类
      

  2.   

    是这样的,我从先从服务器发送了一个Vector文件列表到客户端,然后接着发送以上存储的文件的各个流,现在的情况是,客户端可以完整接收到,我从服务器发送过来的,Vector,至于第一个文件流是可以完全接收到的,可是第二个,第三个。。后面的所有文件都是为0字现在我就是找不出这个原因,好像楼下的兄弟说到了我这点,我服务器,是每次都发送了一个文件流,可是客户端却始终是一个Socket对像在接收,好像确实是这个问题,但是因为客户端,只能实列化一次Socket?我如何才能保证,服务器每次发送过来的,我客户端都会产生一个可以接收不同流的SOCKET?
    请多多指教!
      

  3.   

    一个Stream里面可以干许多事情,你可以用类似http的keep-alive方式
    1 发送文件描述信息
    2 发送文件字节长度
    3 发送对应长度的数据
    4 发送第二个文件描述信息
     ....
      

  4.   

    我还不是很明白你所说的,“类似http的keep-alive”这个是好何用?
      

  5.   

    Sorry, my computer can only input english.
    1) It is better to call getObjectInputStream(), getDataInputStream(), getObjectOutputStream() and getDataOutputStream() only once.2) In your client, there is an error apparently. You first should read the file length, then read the file contents according to the length. The code looks like:
    ...
    long len = dIn.readLong();
    if(dIn!=null ){
    while( len > 0 ){
    int read= (len > bug.length)?buf.length:len;
    if(dIn!=null){
    read=dIn.read(buf, 0, len);
    if( read == -1 ) {
    break;
    } else {
    out.write( buf, 0, read );
    len -= read;
    }

    }
    }
    out.flush();
    out.close();
    }...
      

  6.   

    sorry, the code should look like this:...
    long len = dIn.readLong();
    if(dIn!=null ){
    while( len > 0 ){
    int read= (len > bug.length)?buf.length:len;
    if(dIn!=null){
    read=dIn.read(buf, 0, read);
    if( read == -1 ) {
    break;
    } else {
    out.write( buf, 0, read );
    len -= read;
    }

    }
    }
    out.flush();
    out.close();
    }...
      

  7.   


    非常感谢楼上这位兄弟,我现太改改我的代码。就是我现在还有一点不怎么明白的,因为我的文件夹是从服务器发送过来的,在客户端接收,你叫我把getDataInputStream仅调用一次?
    在这里我就有点迷糊,因为整个客户端只能在程序启动时,实例化(Socket)一次,也就是说它实例化一次话,我整个应用就只能使用getDataInputStream一次?但是我服务器是每次一个文件都发送一Socket呀?
    请兄弟多指点~~~
      

  8.   

    If the DataInputStream buffers your data that read from the under layer socket, your program will not work correctly.Because there is only one socket when transferring the file, so we just need to call the getDataInputStream, getDataOutputStream... only once. This ensures no problem will occur.
      

  9.   


    这位兄弟,如果我的方案不行?你是否有别的,我现在就是要实现文件夹向客户端发送,之前用FTP已写了一个,但是客户方不会开通FTP。于是我才想到SOCKET是否还有其它?请指点~
      

  10.   

    我用RMI实现了,用RMI做文件传输代码量少了一大半。不过还是感谢,回我贴子的兄弟们,一起讨论真好:)