Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-如何通过套接字在字符串之间高效地发送二进制数据?_Java_Sockets - Fatal编程技术网

Java-如何通过套接字在字符串之间高效地发送二进制数据?

Java-如何通过套接字在字符串之间高效地发送二进制数据?,java,sockets,Java,Sockets,我正在制作一个聊天程序,在该程序中,我必须将一个文件分成1024字节的块,并以以下格式通过套接字发送: <DataPacket>Binary_data<DataPacket\> 要将二进制数据分块,通常最好先发送字节数,然后将原始数据作为字节发送。因此,聊天客户端应该首先发送字符串“Packet 711\n”,然后发送文件的711字节(大多数文件大小不是1024的倍数!) 通过这种方式,您可以分块发送数据,并将最后一块尽可能小,以避免损坏文件。大小之后的换行使接收者更

我正在制作一个聊天程序,在该程序中,我必须将一个文件分成1024字节的块,并以以下格式通过套接字发送:

<DataPacket>Binary_data<DataPacket\>

要将二进制数据分块,通常最好先发送字节数,然后将原始数据作为字节发送。因此,聊天客户端应该首先发送字符串“Packet 711\n”,然后发送文件的711字节(大多数文件大小不是1024的倍数!)

通过这种方式,您可以分块发送数据,并将最后一块尽可能小,以避免损坏文件。大小之后的换行使接收者更容易确定数字的结束位置和实际原始数据的开始位置

[编辑]如果您不能对协议进行太多更改,可能这是可行的:
711\n
。。。711字节二进制数据<代码>

因此,发送数据的代码如下所示:

void SendFile(Socket sendingSocket, File fileToSend) {
    OutputStream stream = sendingSocket.getOutputStream();
    InputStream input = new FileInputStream(fileToSend);

    byte[] buffer = new byte[1024];
    int len;
    while(true) {
        len = input.read(buffer);
        if(len < 0) break;

        String header = "<DataPacket>" + len + "\n";
        stream.write(header.getBytes('ASCII'));
        stream.write(buffer, 0, len);
        String footer = "<DataPacket\>";
        stream.write(footer.getBytes('ASCII'));
    }

    input.close();
    stream.close();
}
void SendFile(套接字发送套接字,文件fileToSend){
OutputStream=sendingSocket.getOutputStream();
InputStream输入=新文件InputStream(fileToSend);
字节[]缓冲区=新字节[1024];
内伦;
while(true){
len=输入读取(缓冲区);
如果(len<0)中断;
字符串头=”“+len+“\n”;
stream.write(header.getBytes('ASCII'));
流写入(缓冲区,0,len);
字符串页脚=”;
stream.write(footer.getBytes('ASCII'));
}
input.close();
stream.close();
}

在接收端,您需要解析报头(包括预期的字节数)。然后您可以分配一个缓冲区并读取字节。

您可以发送SOH字符以表示开始,发送ETX以表示消息结束,但最终如果您要定义自己的协议,使用您想要的。@MarkW使用SOH和ETX将帮助流读取器区分标头和数据,或者只是使编写解析代码更容易?抱歉,这不是我自己的协议,因此我只能编写Java代码来实现它。但我有一个问题,我想我会把两个头“”之间的任何内容附加在一起,那么它怎么会损坏文件呢?TCP不能保证这一点吗?当文件包含字符串时会发生什么情况?如果文件长度为15字节,那么会发生什么情况?在文章中指出,如果内容(聊天信息、数据)中有“”,则将其更改为“”,反之亦然。但是我想你是对的,检查数据“这取决于你写的代码。如果你盲目地发送
字节[1024]
,它将始终是1024字节。谢谢!因为我在将文件放入数组之前检查了文件的可用大小,我想可以省略len。如果可以,让我测试一些文件。
"<Packet\>".
void SendFile(Socket sendingSocket, File fileToSend);
void ReceiveFile(Socket receivingSocket);
void SendFile(Socket sendingSocket, File fileToSend) {
    OutputStream stream = sendingSocket.getOutputStream();
    InputStream input = new FileInputStream(fileToSend);

    byte[] buffer = new byte[1024];
    int len;
    while(true) {
        len = input.read(buffer);
        if(len < 0) break;

        String header = "<DataPacket>" + len + "\n";
        stream.write(header.getBytes('ASCII'));
        stream.write(buffer, 0, len);
        String footer = "<DataPacket\>";
        stream.write(footer.getBytes('ASCII'));
    }

    input.close();
    stream.close();
}