套接字中的Java堆内存错误

时间:2012-01-03 00:46:46

标签: java

我正在尝试打开一个套接字并听取。用PHP编写的客户端将发送XML请求。目前我只是发送字符串“test”到它,我得到一个内存堆错误。

这是我的服务器的java代码:

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        server();

    }

    public static void server() {
        ServerSocket MyService = null;
        try {
            MyService = new ServerSocket(3030);
        }
        catch (IOException e) {
            System.out.println(e);
        }

        Socket serviceSocket = null;
        try {
            serviceSocket = MyService.accept();
        }
        catch (IOException e) {
            System.out.println(e);
        }

        DataInputStream in;
        try {
            in = new DataInputStream(serviceSocket.getInputStream());
            System.out.println("DEV STEP 1");
            int len = in.readInt();
            System.out.println(len);
            byte[] xml = new byte[len];
            in.read(xml, 0, len);
            //System.out.print(xml.toString());
            //Document doc = builder.parse(new ByteArrayInputStream(xml));

        }
        catch (IOException e) {
            System.out.println(e);
        }

    }

}

我得到的错误是:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at main.server(main.java:39)
    at main.main(main.java:12)

我已经完成了搜索,这里有很多关于这个错误的解释,但是我无法理解为什么当我发送4个字母时,String len是1952805748。

2 个答案:

答案 0 :(得分:3)

嗯,你得到内存不足的错误,因为len是如此巨大。如果您将数据作为字符发送,然后对其执行readInt(),那么这就是造成问题的原因。您需要将数据读取为字符。

您的数字有效可能是字符串“test”的二进制数。你应该只是从InputStream读取一个字符串,不知道为什么你需要一个DataInputStream,因为它支持读取二进制等,这不是你正在做的事情。只需使用BufferedInputStream,然后对其进行正常读取。

答案 1 :(得分:1)

为了扩展Francis Upton的答案,你得到一个堆异常,因为你试图从传入的套接字流中读取 n 字节,其中 n 表示完全随意您在处理循环开始时读取的整数。我称之为完全随意的原因是因为你从未在客户端代码中实际发送过单独的int。因此,您的代码只是从输入流的前4个字节中的任何内容读取一个int,这可能是任何东西。

查看IOUtils中的Apache Commons IO,它包含一次性读取整个数据流的好方法(toByteArraytoString等。