求救!——socket文件传输+消息验证传输正确性。(附代码)

stillfire 2005-07-03 03:19:41
程序的目的是想使用 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();
}
}

}

...全文
296 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
gyscsdn 2005-10-15
  • 打赏
  • 举报
回复
框架重新定义吧,服务端用至少两个线程,一个负责用于应答处理,一个用于接收二进制数据,
然后由服务端决定文件是否文件接受完毕,在发应答给客户端。


服务端收到一个应答时,另开一个线程用于接收二进制数据,不可以吗?!请参考ftp实现
kingfish 2005-07-04
  • 打赏
  • 举报
回复
while(num!=(-1)) //按你的程序,server段什么时间才能满足=-1的条件? 那就是client断开的时候。


//是不是 无论 client or server 双方都是只管忘里面写东西,但是究竟是否收到,双方都是不知道的
如果能写成功,那么网络正常的话对方当然可以收到。
文件的完整性其实不需要你用这种方式保证,如果收发双方都正常,那么文件传输就是正常的。

或者你可以参考ftp来做,用2个连接,一个传输命令,一个传输数据。
humanity 2005-07-04
  • 打赏
  • 举报
回复
人家 Ftp 怎么打开命令通道和数据通道的?
问问别人然后比较你的情况,
stillfire 2005-07-03
  • 打赏
  • 举报
回复
to kingfish

还有一点问题,是不是 无论 client or server 双方都是只管忘里面写东西,但是究竟是否收到,双方都是不知道的/。
stillfire 2005-07-03
  • 打赏
  • 举报
回复

to : 回复人: gyscsdn(geng)
我不是很理解,怎么样保证 2 个进程不向冲突,但是又能够进行消息通信?

to : 回复人: kingfish(八百里秦川@龙城异客)

我觉得有道理,但是能不能再说的清楚一点:(:P)
经过测试,我发现是如果 两边有while(){ } 去循环读取 stream中的数据的话,必然造成一方挂起,
那么,我必须先把文件的大小发过去,然后再 双方再根据文件的大小判断 文件是否传输完整。
gyscsdn 2005-07-03
  • 打赏
  • 举报
回复
框架重新定义吧,服务端用至少两个线程,一个负责用于应答处理,一个用于接收二进制数据,
然后由服务端决定文件是否文件接受完毕,在发应答给客户端。
kingfish 2005-07-03
  • 打赏
  • 举报
回复
server端根本不知道client文件是否发送完成,所以writer.println("ok");这句根本执行不到。

最好将协议重新约定一下,如client下将文件大小送给server, server根据大小来读取数据。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧