程序的目的是想使用 socket传递文件,server端负责接受文件,client端负责传递文件。在文件传递完毕之后,我想判断文件是否完成,由server端 发送一个ok 消息给client,如果client接受到改文件则判断server端接受文件成功,,,,,,但是程序出现这种情况 
"Welcome "在传文件之前写入 PrintWriter的,这句话在client能够被BufferedReader读取出来
“OK” 在传文件之后写入 PrintWriter,就读不出来了, 在client程序 的 ReadLine就会 挂起!!各位帮忙看看这个是怎么回事?先看看代码
----------------------------
import java.io.*;
import java.net.*;public class FileServer2{public static void main(String[] args)throws Exception{File file=new File("copy.txt");
file.createNewFile();
RandomAccessFile raf=new RandomAccessFile(file,"rw");ServerSocket ss=new ServerSocket(9090);
Socket client=ss.accept();BufferedReader reader=new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintWriter writer=new PrintWriter(
new OutputStreamWriter(client.getOutputStream()),true);
//输出文件流
OutputStream netOut=client.getOutputStream();
OutputStream out=new DataOutputStream(new BufferedOutputStream(netOut));InputStream netIn=client.getInputStream();
InputStream in=new DataInputStream(new BufferedInputStream(netIn));writer.println(" Welcome to the server! Now is : "+new java.util.Date()+" port: "+client.getLocalPort()); //在传文件之前,这句话在client能够读出来//创建文件读取缓冲区
byte[] buf=new byte[2048];
int num=in.read(buf); //每次读取 文件放入缓冲区中。
while(num!=(-1)){//是否读完文件
raf.write(buf,0,num);//把文件数据写出网络缓冲区
raf.skipBytes(num);//刷新缓冲区把数据写往客户端
num=in.read(buf);//继续从文件中读取数据
}
raf.close();writer.println("ok");//在传文件之前,这句话在client就读不出来了System.out.println("传输完毕");
writer.close();
client.close();
ss.close();
}
}------------------------------
import java.io.*;
import java.net.*;public class MyClientSender{
public void fileClient(String ip,String path) throws Exception{
InetAddress addr=InetAddress.getByName(ip);
Socket server=new Socket(addr,9090);
File file=new File(path);
FileInputStream fos=null;
PrintWriter writer=null;
BufferedReader reader=null;
fos=new FileInputStream(file);try {
reader=new BufferedReader(
new InputStreamReader(server.getInputStream()));
writer=new PrintWriter(
new OutputStreamWriter(server.getOutputStream()),true);
OutputStream netOut=server.getOutputStream();
OutputStream out=new DataOutputStream(new BufferedOutputStream(netOut));InputStream netIn=server.getInputStream();
InputStream in=new DataInputStream(new BufferedInputStream(netIn));byte[] buf=new byte[2048];
int num=fos.read(buf);
int i=0;
while(num!=(-1)){//是否读完所有数据
out.write(buf,0,num);//将数据写往socket 流
   out.flush();
num=fos.read(buf);//继续从网络中读取文件
System.out.println((i++)+" isbound ? "+server.isBound()+" isInputShutdown "+server.isInputShutdown()+" isOutputShutdown "+server.isOutputShutdown());
}
fos.close();String str=null;
System.out.println("#####################");
System.out.println("1: "+reader.readLine());//读到 "Welcome to "
System.out.println("2: "+reader.readLine());// 程序挂起
System.out.println("#####################");} catch (IOException e) {
System.err.println("文件传输异常 "+e.getMessage());
} finally {
try {
if (server != null) server.close();
if (reader != null) reader.close();
if (writer != null) writer.close();
} catch (IOException ex) {}
}
}public static void main(String[] args){
MyClientSender o=new MyClientSender();
try {
o.fileClient("192.168.100.147","test.txt");
} catch (Exception e) {
e.printStackTrace();
}
}} 

解决方案 »

  1.   

    server端根本不知道client文件是否发送完成,所以writer.println("ok");这句根本执行不到。最好将协议重新约定一下,如client下将文件大小送给server, server根据大小来读取数据。
      

  2.   


    to : 回复人: gyscsdn(geng) 
    我不是很理解,怎么样保证 2 个进程不向冲突,但是又能够进行消息通信?to : 回复人: kingfish(八百里秦川@龙城异客) 我觉得有道理,但是能不能再说的清楚一点:(:P)  
    经过测试,我发现是如果 两边有while(){ } 去循环读取 stream中的数据的话,必然造成一方挂起,
    那么,我必须先把文件的大小发过去,然后再 双方再根据文件的大小判断 文件是否传输完整。
      

  3.   

    to kingfish还有一点问题,是不是 无论 client or server 双方都是只管忘里面写东西,但是究竟是否收到,双方都是不知道的/。
      

  4.   

    人家 Ftp 怎么打开命令通道和数据通道的?
    问问别人然后比较你的情况,
      

  5.   

    while(num!=(-1))  //按你的程序,server段什么时间才能满足=-1的条件? 那就是client断开的时候。
    //是不是 无论 client or server 双方都是只管忘里面写东西,但是究竟是否收到,双方都是不知道的
    如果能写成功,那么网络正常的话对方当然可以收到。
    文件的完整性其实不需要你用这种方式保证,如果收发双方都正常,那么文件传输就是正常的。或者你可以参考ftp来做,用2个连接,一个传输命令,一个传输数据。
      

  6.   

    框架重新定义吧,服务端用至少两个线程,一个负责用于应答处理,一个用于接收二进制数据,
    然后由服务端决定文件是否文件接受完毕,在发应答给客户端。
    服务端收到一个应答时,另开一个线程用于接收二进制数据,不可以吗?!请参考ftp实现