DataOutputStream:dos.write()循环执行,Receiver仅接收一个数据包

时间:2019-05-16 20:28:53

标签: 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();

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

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

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

有人可以帮助我吗? :)

1 个答案:

答案 0 :(得分:1)

close()上调用DataOutputStream将关闭其关联的OutputStream,而关闭套接字的OutputStream则会关闭该套接字。这是记录的行为。

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

如果要在单个连接中发送多个字符串,请不要在发送方调用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();
    }
}