黑马程序员技术交流社区

标题: 为什么我TCP丢失数据了??? [打印本页]

作者: wygsqsj    时间: 2015-12-8 22:27
标题: 为什么我TCP丢失数据了???
求大神帮忙分析下,为什么我在TCP传输的时候先把文件名传给服务端,然后再把文件上传到服务端时会出现数据丢失的情况啊,是因为我开了两次输出流的缘故么?我把第一次写文件名的几行去掉后文件就完整了,为什么???
客户端是:
  1. package edu.heima.tcptest3;

  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedReader;
  4. import java.io.FileInputStream;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStream;
  7. import java.io.PrintWriter;
  8. import java.net.Socket;

  9. /*
  10. * 上传MP3文件,客户端
  11. * 1.建立客户端
  12. * 2.建立字节读取流获取本地的MP3文件
  13. * 3.获取Socket中的输出流,把本地文件写入到输出流中
  14. * 4.获取Socket输入流,得到服务端反馈数据
  15. * 5.关闭资源
  16. * */
  17. public class Client {

  18.         public static void main(String[] args)throws Exception {
  19.                

  20.                         //建立Socket客户端
  21.                         Socket s = new Socket("127.0.0.1",8889);
  22.                        
  23.                         //告诉服务器文件的名称
  24.                         PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  25.                         pw.println("那个女孩.mp3");
  26.                        
  27.                         //获取本地文件,通过字节流
  28.                         BufferedInputStream bis = new BufferedInputStream(
  29.                                                                                         new FileInputStream("d://音乐//那个女孩.mp3"));
  30.                        
  31.                         //获取输出流
  32.                         OutputStream ps = s.getOutputStream();
  33.                         //将获取到文件数据写入到输出流中
  34.                         byte[] buf = new byte[1024];
  35.                         int len = 0;
  36.                         while((len = bis.read(buf))!=-1)
  37.                         {
  38.                                 ps.write(buf, 0, len);
  39.                         }
  40.                         //写入结束标记
  41.                         s.shutdownOutput();
  42.                         //获取输入流
  43.                         BufferedReader br = new BufferedReader(
  44.                                                                         new InputStreamReader(s.getInputStream()));
  45.                         System.out.println(br.readLine());
  46.                         //关资源
  47.                         bis.close();
  48.                         s.close();
  49.        
  50.         }

  51. }
复制代码


服务端是:
  1. package edu.heima.tcptest3;

  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedReader;
  4. import java.io.BufferedWriter;
  5. import java.io.FileOutputStream;
  6. import java.io.InputStreamReader;
  7. import java.io.OutputStreamWriter;
  8. import java.io.PrintStream;
  9. import java.io.PrintWriter;
  10. import java.net.ServerSocket;
  11. import java.net.Socket;

  12. /*
  13. * 并发上传文件,服务端
  14. * 1.建立服务端,获取客户端对象
  15. * 2.每获取到一个客户端对象就开启一条线程
  16. * 3.在线程类中封装一下内容
  17. *                 首先获取到文件名字
  18. *                  获取客户端对象的输入流,读取数据
  19. *                 建立新的输出流,将Socket中的数据写入到本地磁盘
  20. *                 完成后关闭客户端对象
  21. * */
  22. //定义一个线程类
  23. class PicThread implements Runnable{
  24.         //接收一个客户端对象
  25.         private Socket s;
  26.         PicThread(Socket s)
  27.         {
  28.                 this.s = s;
  29.         }
  30.         public void run()
  31.         {
  32.                 //获取客户端ip
  33.                 String ip = s.getInetAddress().getHostAddress();
  34.                 System.out.println(ip+"run time...");
  35.                 try {
  36.                         //获取文件名字
  37.                         BufferedReader br = new BufferedReader(
  38.                                                                         new InputStreamReader(s.getInputStream()));
  39.                         String fileName = br.readLine();
  40.                        
  41.                        
  42.                         //获取客户端对象的输入流
  43.                         BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
  44.                         //建立输出流,写入到本地磁盘中
  45.                         PrintStream ps = new PrintStream(new FileOutputStream("e://"+fileName));
  46.                         //读取客户端中的数据,写入到指定的文件中
  47.                         byte[] buf = new byte[1024];
  48.                         int len = 0;
  49.                         while((len = bis.read(buf))!=-1)
  50.                         {
  51.                                 ps.write(buf, 0, len);
  52.                         }
  53.                         //反馈信息给服务端
  54.                         PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  55.                         pw.println("数据上传成功!");
  56.                         //关闭资源
  57.                         s.close();
  58.                         ps.close();
  59.                 } catch (Exception e) {
  60.                         throw new RuntimeException(ip+"上传失败!");
  61.                 }
  62.                
  63.         }
  64. }
  65. public class Server {

  66.         public static void main(String[] args)throws Exception {
  67.                 //服务端一般不关闭,通过accept阻塞式方法来获取连接建立的客户端
  68.                 //建立服务端
  69.                 ServerSocket ss = new ServerSocket(8889);
  70.                 while(true)
  71.                 {
  72.                         //获取客户端
  73.                         Socket s = ss.accept();
  74.                         //每获取到一个客户端就开启一条线程
  75.                         new Thread(new PicThread(s)).start();
  76.                 }
  77.         }
  78. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2