黑马程序员技术交流社区

标题: 如何解决TCP中丢包的问题 [打印本页]

作者: hello_world!    时间: 2012-10-23 19:18
标题: 如何解决TCP中丢包的问题
在TCP上传文件的练习中。毕老师讲课的时候,演示的时候没有发生数据丢失的情况。但是,我将代码多运行几次,发生数据丢失的情况。这种情况是避免不了的。但是可以补救?求方法?
这里有上传文件的代码。给大家实验之用。
客户端:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class TransClient {


        public static void main(String[] args) {
                try {
                        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 10010);
                        OutputStream out = socket.getOutputStream();
                                               
                        Scanner scanner = new Scanner(System.in);
                        File file = null;
                        while (true) {
                                System.out.println("Please put in the name of file:");
                                String fileName = scanner.nextLine();
                                file = new File(fileName);
                               
                                if (!file.exists()) {
                                        System.out.println(fileName + " isn't exists");
                                }else{
                                        break;
                                }
                        }
                       
                        PrintWriter pw = new PrintWriter(out, true);
                        pw.println(file.getName());                                        //发送文件名
                       
                        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                        BufferedOutputStream bos = new BufferedOutputStream(out);
                        byte[] buf = new byte[1024*16];
                        int len;
                        while (-1 != (len = bis.read(buf))) {
                                bos.write(buf, 0, len);
                                bos.flush();//注意这里一定要刷新,要不然数据没有出缓冲区。更谈不上发送了
                        }
                       
                        socket.shutdownOutput();
                       
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        System.out.println(br.readLine());
                       
                        bis.close();
                        socket.close();//是不是与socket相关的流,都被关闭了                       
                } catch (UnknownHostException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }               
}

服务器端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.List;

public class TransServer {

        public static void main(String[] args) {
                try {
                        ServerSocket ss = new ServerSocket(10010);
                        while (true) {
                                Socket socket = ss.accept();
                                new Thread(new ServerRunnable(socket)).start();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
               
        }
       
       
}

class ServerRunnable implements Runnable{

        private Socket s;
       
        public ServerRunnable(Socket socket) {
                super();
                this.s = socket;
        }

        @Override
        public void run() {
                try {
                       
                        System.out.println(s.getInetAddress().getHostAddress() + "...contected");
                        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
                        File file = new File(br.readLine());                                //获得文件名
                       
                        BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
                       
                        String fileName = null;
                        File dest = new File("D:\\");
                        String[] names = dest.list();
                        List<String> list = Arrays.asList(names);
                        int count = 1;
                        if (list.contains(file.getName())) {//这段代码作用是,如果存在相同名字的文件,那就这样处理fileName(count).***;fileName代表文件名(代表不带后缀的文件名),count重复的个数,***代表文件名的后缀
                                String shortName = file.getName();
                                while (list.contains(shortName.substring(0, shortName.lastIndexOf('.')) + "(" + count + ")" + shortName.substring(shortName.lastIndexOf('.')))) {       
                                        count++;
                                }
                                fileName = shortName.substring(0, shortName.lastIndexOf('.')) + "(" + count + ")" + shortName.substring(shortName.lastIndexOf('.'));
                        }else{
                                fileName = file.getName();
                        }
                        System.out.println(fileName);
                       
                        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\" + fileName));
                       
                        byte[] buf = new byte[1024*16];
                        int len;
                        while (-1 != (len = bis.read(buf))) {
                                bos.write(buf, 0, len);                               
                        }
                       
                        bos.flush();
                       
                        PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
                        pw.println("上传成功");//这里就不要用write(),因为它不会自动刷新的
                       
                        s.shutdownOutput();
                       
                        bos.close();
                        s.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }       
}

等待高手解答。。。








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