我正在尝试在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,因为目标机器是未知的。
答案 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流发送“消息”,当完全发送消息时,可能会或可能不会关闭。