2017-02-24 87 views
0

我有一个Socket连接到COM-Server ++从W & T连接到互联网,并通过串行到USB连接到我的PC。从套接字的InputStream读取

的COM服务器为TCP站通信的设置为:

ACTIV。数据包选项:已禁用
无效。超时:00030
连接。超时:00300
断开字符:000
客户: “C” +地址:禁用
响应模式:禁用

在我的应用程序阅读这个服务器这样的输入数据:

boolean running = true; 
log.info("{0}: Starting to listen for input data", name); 
while (running) 
{ 
    try 
    { 
    int charsRead = inputStream.read(buffer); 

    if (charsRead < 0) 
    { 
     running = false; 
    } 
    else 
    { 
     byte[] received = Arrays.copyOf(buffer, charsRead); 
     /** TODO: Call interface of protocol here */ 
     log.info("{0}: data received: {1}", connection.getName(), new String(received)); 
    } 
    } 
    catch (IOException ie) 
    { 
    setStatus(ConnectionStatus.FAILURE); 
    close(); 
    /** TODO: Exception handling */ 
    running = false; 
    } 
} 

如果我派:test<CR><LF>从设备日志输出我得到的是:

(terminal1) terminal1: data received: t 
(terminal1) terminal1: data received: e 
(terminal1) terminal1: data received: st 
(terminal1) terminal1: data received: 
(terminal1) terminal1: data received: 

所需的输出不过是:

(terminal1) terminal1: data received: test 

我的错误在哪里?或者我假设InputStream的读取方法的错误工作流程?

+1

[DOC](https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html) 公共抽象INT读() 抛出IOException异常 读取的下一个数据字节从输入流
public int read(byte [] b) throws IOException 从输入流中读取一定数量的字节 – mihatel

+0

噢好吧,所以他不会读到最后。在技​​术上等待完成时间,然后注销缓冲区将会返回预期的结果,我正确吗? – Nico

+1

只需将读取的内容追加到数组中直到它结束,全部为 – mihatel

回答

3

一个简单的解决看起来像这样:

StringBuilder sb = new StringBuilder(); 

int c; 

while (((c = inputStream.read()) >= 0) && (c != 0x0a /* <LF> */)) { 
    if (c != 0x0d /* <CR> */) { 
    sb.append((char)c); 
    } else { 
    // Ignore <CR>. 
    } 
} 

return sb.toString(); 

此代码保持直到一个线(或流的末尾)的端部被发现,通过用信号通知<LF>读取字节。

我们预计<CR><LF>其中<CR>是行分隔符的一部分,所以我们只是忽略任何<CR>同时收集所有其他字节。

+0

这就是我需要的:)谢谢你,非常好想法使用inputStream本身循环。想知道为什么我没有想到 – Nico

+0

快速的问题。 我再次测试了一遍,发现大约30秒后流关闭。我附加了另一个while循环来继续循环,而套接字仍然连接到远程设备。尽管在我看来这是一个肮脏的黑客攻击。那么是否有更好的方法来保持流始终打开? – Nico

+0

“Inactiv。Timeout:00030” - 您可能需要在这30秒内发送*东西,让设备知道您还在那里。否则,设备可能会认为连接处于“非活动状态”并关闭它。 – JimmyB

0

我不完全知道这个库。但是流返回什么它得到,并没有人保证,它实际上是这一切... 这可能会解决你的问题:How to read all of Inputstream in Server Socket JAVA

编辑:您也可以尝试使用ObjectInputStream的(如果可能的话)来获得字符串作为对象。

+0

我只是使用'java.net.Socket',这个socket有一个你得到的InputStream,而类是'java.io.InputStream',所以它基本上是vanilla Java。我只是想给那些可能知道更具体问题的人提供COM-Server信息。 我会看看上面提到的方法 – Nico

+0

我刚刚检查过它,函数readFully()不适用于我。我只是有read(),read(byte []),skip,reset,close和read(byte [],int,int)... Eclipse和doc告诉我它是java.io.InputStream,但是.. – Nico

+0

@kleopi:请检查之前评论 [回答@Lolo](http://stackoverflow.com/a/25900095/3266248) – mihatel