黑马程序员技术交流社区
标题:
关于tcp复制文件方法阻塞问题
[打印本页]
作者:
周恺
时间:
2012-7-6 01:14
标题:
关于tcp复制文件方法阻塞问题
本帖最后由 周恺 于 2012-7-18 08:12 编辑
今天看到毕老师的tcp复制文件的视频有点不明白:
import java.io.*;
import java.net.*;
class TextClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("KLO-PC",10006);
BufferedReader bufr =
new BufferedReader(new FileReader("f://ArrayTest2.java"));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null)
{
out.println(line);
}
//s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1.
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = bufIn.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}
class TextServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("f://ArrayTest2_copy.java"),true);
String line = null;
while((line=bufIn.readLine())!=null)
{
//if("over".equals(line))
//break;
out.println(line);
}
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
out.close();
s.close();
ss.close();
}
}
复制代码
这是毕老师未修正的代码,他老人家说,这样写服务器端的readLine()方法会因为客户端没有传来停止标示会一直阻塞,这里我不太明白,while((line=bufIn.readLine())!=null)
不是有停止循环的条件了吗?readLine()运行到流结尾不就退出循环了吗?
我在看视频前自己写了一段代码:
import java.net.*;
import java.io.*;
class TextClient
{
public static void main(String[] args)throws Exception
{
long startTime=System.currentTimeMillis();
Socket s=new Socket("KLO-PC",10007);
FileInputStream fis=new FileInputStream("d://javaAPI.chm");
OutputStream nos=s.getOutputStream();
byte buff[]=new byte[1024*1024];
//byte buff;
int len;
while((len=fis.read(buff))!=-1)
{
nos.write(buff,0,len);
//nos.write(buff);
nos.flush();
}
//s.close();
//fis.close();
long overTime=System.currentTimeMillis();
p.sop("传输时间为"+(overTime-startTime)+"毫秒");
}
}
class TextServer
{
public static void main(String args[])throws Exception
{
ServerSocket ss=new ServerSocket(10007);
Socket s=ss.accept();
p.sopln("已接收到IP::"+s.getInetAddress().getHostAddress()+"::的连接....");
InputStream nis=s.getInputStream();
File f=new File("d://javaAPI.chm");
FileOutputStream fos=new FileOutputStream(f);
byte buff[]=new byte[1024*1024];
int len;
long fileLen=0;
while ((len=nis.read(buff))!=-1)
{
fos.write(buff,0,len);
fos.flush();
fileLen+=f.length();
p.sopln("已接收到"+fileLen+"字节");
}
p.sopln("接收完成");
ss.close();
fos.close();
}
}
复制代码
我使用的是字节流传输,但是我也是用了阻塞式方法read(),也没有从客户端传什么停止标识.为什么就可以正常传输呢?
作者:
温少邦
时间:
2012-7-6 06:56
1.
Server那边
while((line=bufIn.readLine())!=null)是可以退出循环
但是Client那边在从一个文件里面读取时用的条件是while((line=bufr.readLine())!=null)
当Client读到文件结尾了 这个while循环就跳出去了
Client就不传东西过去了
Client知道文件到结尾了
但是没有告诉Server
所以Server那边还在等数据
s.shutdownOutput()就是告诉Server那边文件到结尾了
2.
毕老师的代码中,Client传完后,要等待Server传回一个"上传成功的信息"
所以也调用了read()阻塞方法
这样2边都在等待
就出问题了.
至于为什么你用字节流就可以正常传
我感觉是这样
如果Client那边传完之后不等Server的返回信息
直接把Socket给close了
那流也给close了
Server那边想等着read也等不了了
于是就正常结束了
不过我看你的代码里把s.close()注释掉了?
这样应该会有Server那边应该会有connection reset异常
但是文件还是传过去了
应该相当于强行中断了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2