如何使用readline而没有和EOF字符java

时间:2011-03-31 15:55:24

标签: java sockets readline eof

我正在尝试在java中实现一个简单的服务器应用程序。

它只是在tcp / ip上的消息中读取并将其存储为字符串,这是我的代码。

    try{
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    } catch (IOException e) {
        System.out.println("cannot open input buffer");
        System.exit(-1);
    }

    clientSocket.setSoTimeout(5000);

    //read first bit of message
    message = in.readLine();
    System.out.println(message);
    //as message is an undefined length we need to loop and check for the springer miller 
    //end mark /Request
    while(message.contains("/Request") == false  )
    {
        try {
        message = in.readLine();
        System.out.println(message);
        }
        catch (IOException e) {
            System.out.println("cannot open input buffer");
            System.exit(-1);
        }
    }       

    //reply
    out.println(outputLine);

我遇到的问题是该消息似乎没有EOF。这是我正在翻译成我的另一个公司协议,这就是程序的目的所以我不能在消息中添加EOF

如果我运行该程序,获取的信息是:

POST / HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: http://htng.org/1.1/Listener.Wsdl#ReceiveMessageAsync
User-Agent: Java/1.6.0_24
Host: 192.168.0.32:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 3009

然后它应该在它应该读取消息正文时挂起。

我之前从未使用过Java,也不想写一个二进制套接字来检测我自己的EOF。

有没有办法读取x秒然后返回

谢谢你的帮助。

P.S已经用C ++成功构建了程序,但需要移植到java,因为目标机器是未知的。

2 个答案:

答案 0 :(得分:1)

BufferedReader.readline将在EOF上返回null并且不会抛出异常。

此外,“其他公司协议”似乎是SOAP over HTTP。 也许你想使用HTTP或SOAP库?这里的其他人将能够指点......

否则您可以使用以下方法: readLine一次检查方法是否确实是POST(否则Content-Length标头可能不存在)并且路径正确。
readLine,直到它返回一个空行(或null),以读取所有HTTP头。 在执行此操作时,请注意以Content-Length开头的行,以确定以下XML数据的长度。 创建一个正确长度的char []并使用in.read(cbuf, 0, cbuf.length)将xml读入创建的缓冲区cbuf。

答案 1 :(得分:0)

在TCP / IP之上实现协议非常棘手,需要对网络,套接字和操作系统的I / O工作方式有很多了解。

此外,除了网络复杂性之外,实施HTTP非常复杂。

我礼貌地建议你可能处于深水状态,因为你必须在这个级别提问,并且可能需要更多的帮助,而不是你可以得到的。

...反正。

如果您正在阅读的服务器正在尝试与http通话,请使用现有组件。 Apache HttpComponents可能是个不错的选择。我真的不买它伪造http标头,我建议你跳过你的“轻量级”方法。

以下是一些网络i / o基本事实。

网络写入是面向数据包的。 Tcp / ip通常尝试尽可能多地填充每个数据包(使用一些智能算法)。这意味着如果你写4000字节,消息将被分成几个任意大小的数据包,但通常小于1500字节 - 具体取决于网络设备。这也意味着 如果您写的数据包少于一个数据包,您的写入可能会合并到一个数据包中。 (数据包也可以沿着它们分割和合并。)

为了通过流发送消息(它本身是以数据包形式传输的......),您需要事先知道消息的长度,或者读取一个完整的数据包(将.read()写入一个大的缓冲区),解析内容,以一些聪明的方式提取和构造完整的消息。究竟是什么http。 (事情之中)

TCP / IP当然不是面向行的,所以你的新行完全被忽略了。 HTTP使用内容长度(以及一些其他技巧,因为它可能并不总是被定义)通过单个tcp / ip流发送“消息”,当完全发送消息时,可能会或可能不会关闭。