TCP 文件传输问题

发布于 2024-10-03 16:22:18 字数 705 浏览 4 评论 0原文

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 套接字发送协议后,我查看了正在发送的字节。他们都是独一无二的。但在接收方,接收到的字节只是一遍又一遍相同的 byte[]。

三.例子

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]

I. Introduction

I am opening and reading from a file, sending chunks of data through a TCP socket as I read.

SENDER CODE

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

RECEIVER CODE

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

II. Problem

After I send the protocol through the TCP socket, I view the bytes being sent over. They are all unique. BUT at the receiver side, the bytes received is just the same byte[] over and over.

III. Example

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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔戏命师 2024-10-10 16:22:18

您遇到的一个问题是您没有检查收到的字节数。可能您几乎每次通过环回都会获得完整的缓冲区,但您不太可能通过真实网络获得此缓冲区。您必须记录读入缓冲区的字节数并仅使用该数量。

One problem you have is that you don't check how many bytes you recieved. It may be that you get a full buffer almost every time over loopback, but you are unlikely to get this over a real network. You have to record how many bytes were read into the buffer and use only that amount.

为你拒绝所有暧昧 2024-10-10 16:22:18

也许我所做的这个测试示例清楚地表明了您错过了什么:

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();
            }
        }
    }
}

Maybe this test example I did makes it clear what you have missed:

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();
            }
        }
    }
}
鹊巢 2024-10-10 16:22:18

写入所有信息后使用out.flush()

use out.flush() after writing all the information.

怼怹恏 2024-10-10 16:22:18

什么是 FileTransfer,它的构造函数是否复制缓冲区?它的操作是异步的吗?它的缓冲区可能在复制到 TCP 套接字之前被循环重新填充。即,您不断将指向同一缓冲区的指针排队,然后在循环中覆盖该缓冲区。

使 FileTransfer 承担缓冲区参数的所有权,并在发送时将其删除。然后为循环中的每次行程分配一个新的,并将其交给 FileTransfer。

What's FileTransfer, and does its constructor copy the buffer? Is its operation asynchronous? It could be that its buffer gets refilled by the loop before it has been copied to the TCP socket. I.e., you keep queueing up pointers to the same buffer, which you then overwrite in the loop.

Make FileTransfer assume ownership of the buffer parameter, deleting it when sent. Then allocate a fresh one for each trip through the loop and hand it off to the FileTransfer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文