java - DataOutputStream:dos.write() in loop,Receiver只接收一个数据包

标签 java android sockets dataoutputstream

我的 TCP 连接有问题。我通过智能手机通过 TCP 套接字连接将数据(简单字符串)发送到平板电脑。连接工作正常,数据按预期传输。但是当我做一个循环并且在每次迭代中 dos.write() 被触发时,只有一个包到达平板电脑数据接收器。我究竟做错了什么?

这是我连接的发送部分。它遍历列表并将每个数据写入 DataOutputStream .

for(int i = 0; i <= logList.length - 1; ++i){
    String backupPayload = invertLogStringToJson(logList[i]);

    dos = new DataOutputStream(s.getOutputStream());

    dos.writeUTF(backupPayload);
    dos.flush();
    dos.close();

在平板电脑上,我通过以下代码 fragment 接收数据:

@Override
public void run() {
    try {

        while(true){
            mySocket = ss.accept();
            dis = new DataInputStream(mySocket.getInputStream());
            message = dis.readUTF();

            handler.post(() -> {
                bufferIntentSendCode.putExtra("data", message);
                ctx.sendBroadcast(bufferIntentSendCode);
            });
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

正如我所说,当我只发送一个数据包时,连接工作正常。但是如果我想在循环内发送多个包裹,只有第一个包裹会到达目的地。

谁能帮我? :)

最佳答案

调用close()DataOutputStream关闭其关联的 OutputStream , 并关闭套接字的 OutputStream关闭套接字。这是记录在案的行为。

但是,这应该没问题,因为您的接收器代码无论如何都只希望接收 1 个单个字符串。您调用dis.readUTF()每个 TCP 连接只有一次。

如果你想在一个连接中发送多个字符串,不要调用 dos.close()在发送端(至少在发送完所有字符串之前),并调用 dis.readUTF()在接收端循环,直到收到所有字符串。

dos = new DataOutputStream(s.getOutputStream());

for(int i = 0; i < logList.length; ++i){
    String backupPayload = invertLogStringToJson(logList[i]);
    dos.writeUTF(backupPayload);
}
dos.flush();

dos.close();

@Override
public void run() {
    try {
        while (true) {
            mySocket = ss.accept();
            dis = new DataInputStream(mySocket.getInputStream());

            try {
                while (true) {
                    message = dis.readUTF();
                    handler.post(() -> {
                        bufferIntentSendCode.putExtra("data", message);
                        ctx.sendBroadcast(bufferIntentSendCode);
                    });
                }
            } catch (IOException e) {
            }

            dis.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

或者,在发送实际字符串之前发送列表长度,然后在读取字符串之前读取长度:

dos = new DataOutputStream(s.getOutputStream());

// maybe other things first...

dos.writeInt(logList.length);
for(int i = 0; i < logList.length; ++i){
    String backupPayload = invertLogStringToJson(logList[i]);
    dos.writeUTF(backupPayload);
}
dos.flush();

// maybe other things next...

dos.close();

@Override
public void run() {
    try {
        while (true) {
            mySocket = ss.accept();
            dis = new DataInputStream(mySocket.getInputStream());

            try {
                // maybe other things first...

                int length = dis.readInt();
                for (int i = 0; i < length; ++i) {
                    message = dis.readUTF();
                    handler.post(() -> {
                        bufferIntentSendCode.putExtra("data", message);
                        ctx.sendBroadcast(bufferIntentSendCode);
                    });
                }

                // maybe other things next...

            } catch (IOException e) {
            }

            dis.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

关于java - DataOutputStream:dos.write() in loop,Receiver只接收一个数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56176160/

相关文章:

java - 如何在 Google Cloud Console 的同意屏幕上更改电子邮件帐户?

java - 在测试中注入(inject) EntityManager 时,Powermock 和 Spring 导致 ConversionException

java - AsyncTask 更改 BaseAdapter (ListAdapter) 中的 ViewGroup 属性

c - 使用套接字将相同的变量发送到多个客户端进程

c++ - 写入套接字接收的进程字符串的输入

java - 415(不支持的媒体类型)与 jquery

java - 当用户触摸屏幕上的任意位置时,如何一一填充Recycler View ?

android - 搜索我在Google Play上发布的应用程序

java - 适配器上的 notifydataSetChanged 将更新新项目,但不会更新现有项目

mySQL 5.7.13 源安装未创建 mysqld.sock