Java TCP Socket 发送字节数组

Posted

技术标签:

【中文标题】Java TCP Socket 发送字节数组【英文标题】:Java TCP Socket send byte array 【发布时间】:2011-05-10 03:48:37 【问题描述】:

我正在尝试使用 Java TCP 套接字构建文件服务器。当我尝试发送超过几 KB 的文件时,我不断收到错误消息。错误如下:

Exception in thread "main" java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at fileServer.TCPServer.main(TCPServer.java:193)

我正在创建这样的输出流:

OutputStream output = clientSocket.getOutputStream()

而错误源于这一行: output.write(sendData, 0, sendData.length)

其中 sendData 是一个字节数组,我手工制作到一个商定的“协议”,它是 28 个标头字节以及文件。它出错的文件大约是 780kB,而 2kB 的文件可以完美运行。有什么想法吗?

编辑:一些关于我如何制作套接字的附加上下文。

            Socket clientSocket = listenSocket.accept();
        System.out.println("server is listening...");

        DataInputStream input = new DataInputStream(clientSocket.getInputStream());
        OutputStream output = clientSocket.getOutputStream();



        //receive the request packet
        //int nb = input.readInt();
        System.out.println("Read Length " + "28");
        byte[] sentence = new byte[28];
        for(int i=0; i<28; i++)
            sentence[i] = input.readByte();
        

这就是我发送数据的方式: sendData 是我为发送而构建的字节数组 tArray 是我正在处理到 sendData 以发送的文件的字节数组

for(int i = 0; i<filSize; i++)
   //loads into the packet being built
   //needed to minus 36 since all the header info
   endData[i+36] = tArray[i];

System.out.println("send packet size: " + sendData.length);

System.out.print(sendData);
System.out.println("File size is: " + filSize);
int sendDataLength = sendData.length;
try
    output.write(sendData, 0, sendDataLength);
catch (IOException e)
    System.out.println("Error: " + e.getMessage());

clientSocket.close();

编辑 2: 我使用了try catch,现在得到了这个错误:软件导致连接中止:套接字写入错误

【问题讨论】:

【参考方案1】:

Socket reset by peer表示对端连接不正确。检查您的客户端是否正确地保持套接字打开。

编辑:假设您使用的是这样的代码,您不应该使用 DataInputStream。如果您想使用readByte 接收数据,您必须在发送端使用writeByte。您的套接字重置可能正在发生,因为 readByte 调用没有得到它期望的东西。不要使用 DataInputStream:使用 BufferedInputStream 并使用 read 方法。

【讨论】:

使用 2 种不同语言的 2 个不同客户端我仍然收到错误消息。到目前为止,我在没有错误的情况下工作的最大文件是 12kB。 好吧,你可能在两个客户端都犯了同样的错误。您是否在两个客户端中都正确读取了传入数据?没有任何密码就很难破译。 我添加了更多服务器端代码,但目前我无法访问客户端代码。如果到目前为止我为服务器显示的内容没有任何问题,我会从另一台计算机上获取它。 @Fermi,readByte() 无法得到它不期望的东西——它从流中读取一个字节。它当然不能直接导致远端发出断开连接。根据客户端发送数据的方式,在这里使用 DataInputStream 可能是一个非常好的解决方案。 @davmac:见download.oracle.com/javase/6/docs/api/java/io/…。它指出请参阅DataInput 的readByte 方法的一般约定。。如果您查看 DataInput(download.oracle.com/javase/6/docs/api/java/io/…),它会说 此方法适用于读取由接口 DataOutput 的 writeByte 方法写入的字节。我不确定 DataOutput 的 writeByte 是否产生与标准 OutputStream 的 write 相同的数据。【参考方案2】:

我也搜索过类似的问题。

很少提及的原因之一是浏览器上的缓存问题。由于某些意外的缓存逻辑,某些浏览器会重置连接。

要解决这个问题,请在 servlet 的开头使用这行代码。

response.addHeader("Cache-Control", "no-transform, max-age=0");

我从Servlet to load video file from server 得到了这个答案。这可能不是 100% 相同的问题原因,但值得一试。

【讨论】:

以上是关于Java TCP Socket 发送字节数组的主要内容,如果未能解决你的问题,请参考以下文章

用socket发送接收数据,但每次接收的数据字节长度都大于发送的25个字节?

TCP沾包问题

python发送字节数据

非阻塞 UDP 写入返回的字节数是不是少于请求的字节数?

可以为 python 的 socket.recvfrom() 设置最小字节数吗?

发送流终止字节以指示 TCP 流结束