Проблема передачи файлов по протоколу TCP - PullRequest
0 голосов
/ 22 ноября 2010

I. Введение

Я открываю и читаю из файла, отправляю порции данных через сокет TCP во время чтения.

КОД ОТПРАВЛЕНИЯ

byte[] buffer = new byte[16384];
while ((in.read(buffer)) > 0)
{
    SendProtocol(new FileTransfer(sender, receiver, buffer);
}

КОД ПОЛУЧАТЕЛЯ

if(o instanceOf FileTransfer)
    FileTransfer tf = (FileTransfer) o;
    out.write(tf.getData);
}

II. Проблема

После того, как я отправляю протокол через сокет TCP, я просматриваю отправленные байты. Все они уникальны. НО на стороне получателя полученные байты - это один и тот же байт [] снова и снова.

III. Пример

SENDER BYTES  
[3, 3, 5, -44, 4, 3]      
[99, -3, 5, -44, 7, 3]
[-11, 3, 5, -44, 4, 7]
[10, 6, 5, -44, 4, 66]

RECEIVER BYTES
[3, 3, 5, -44, 4, 3]
[3, 3, 5, -44, 4, 3]
[3, 3, 5, -44, 4, 3]
[3, 3, 5, -44, 4, 3]

Ответы [ 4 ]

2 голосов
/ 22 ноября 2010

Может быть, этот тестовый пример, который я сделал, проясняет, что вы пропустили:

public class Test {
    public static void main(String args[]) throws Exception {

        Server server = new Server(12345);

        Socket s = null;
        InputStream fs = null; 
        try {
            s = new Socket("localhost", 12345);
            fs = new FileInputStream("test.txt");

            OutputStream os = s.getOutputStream();
            byte[] bytes = new byte[1024];
            int read;
            while ((read = fs.read(bytes)) != -1)
                os.write(bytes, 0, read);
        }
        finally {
            if (s != null)
                s.close();
            if (fs != null)
                fs.close();
        }


        server.join();
    }

    static class Server extends Thread {

        ServerSocket serverSocket;

        Server(int port) throws IOException {
            serverSocket = new ServerSocket(port);

            start();
        }

        @Override
        public void run() {
            try {
                Socket s = serverSocket.accept();

                InputStream is = s.getInputStream();

                try {

                    StringBuffer sb = new StringBuffer();
                    {
                        byte[] bytes = new byte[1024];
                        int read;
                        while ((read = is.read(bytes)) != -1) 
                            sb.append(new String(bytes, 0, read));
                    }

                    System.out.println(sb);
                }
                finally {
                    if (is != null)
                        is.close();
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
2 голосов
/ 22 ноября 2010

Одна из ваших проблем заключается в том, что вы не проверяете, сколько байтов вы получили. Может случиться так, что вы получаете полный буфер почти каждый раз по петле, но вы вряд ли получите это по реальной сети. Вы должны записать, сколько байтов было считано в буфер и использовать только это количество.

0 голосов
/ 22 ноября 2010

Что такое FileTransfer и копирует ли его конструктор буфер? Является ли его работа асинхронной? Может случиться так, что его буфер заполняется циклом, прежде чем он будет скопирован в сокет TCP. Т.е. вы продолжаете помещать в очередь указатели на тот же буфер, который затем перезаписываете в цикле.

Заставить FileTransfer взять на себя владение параметром буфера, удаляя его при отправке. Затем выделите новый для каждой поездки через цикл и передайте его в FileTransfer.

0 голосов
/ 22 ноября 2010

используйте out.flush() после записи всей информации.

...