2014-01-20 81 views
1

所以。我有一个PHP套接字服务器和Java套接字客户端。
也许这是一个愚蠢的问题......但我没有找到答案。
在客户端,我需要从输入流中读取传入字节并将它们放入字节数组中。
我试着这样做:如何从Java中的字节流中读取(PHP/Java套接字通信)

[客户端(JAVA)]

public static byte[] read(BufferedInputStream in) 
{ 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[32768]; 
    while (true) { 
     int readBytesCount = in.read(buffer); 
     if (readBytesCount == -1) { 
      break; 
     } 
     if (readBytesCount > 0) { 
      baos.write(buffer, 0, readBytesCount); 
     } 
    } 
    baos.flush(); 
    baos.close(); 
    return baos.toByteArray(); 
} 

[SERVER(PHP)

function write(&$client, $message) 
{ 
    $message = explode("\n", $message); 
    foreach ($message as $line) 
    { 
     socket_write($client['sock'], $line."\0"); 
    } 
} 

但是,当它读取的所有字节,在.read()不返回-1,所以循环不停止。 有一次,它返回13(长度),然后 - 没有。 有什么建议吗?

已解决!
[客户端(JAVA)]

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] buffer = new byte[32768]; 
while (true) { 
    int readBytesCount = in.read(buffer); 
    if (getString(buffer).contains("#!EOS!#")) { 
     baos.flush(); 
     baos.close(); 
     return baos.toByteArray(); 
    } 
    if (readBytesCount > 0) { 
     baos.write(buffer, 0, readBytesCount - 1); 
    } 
} 

[SERVER(PHP)

function write(&$client, $message) 
{ 
    $message = explode("\n", $message); 
    $message = str_replace("\r", "", $message); 
    foreach ($message as $line) 
    { 
     rLog("Write to ".$client['ip'].": ".$line); 
     socket_write($client['sock'], $line."\0") or die("[".date('Y-m-d H:i:s')."] Could not write to socket\n"); 
    } 
    socket_write($client['sock'], "#!EOS!#"); 
} 
+0

@ user2310289我认为有关闭流或类似这样的问题... – RussianVodka

+0

读完字节后(它们已经在缓冲区中),将它们追加到另一个数组中。 我不确定这是否会导致您的问题。 –

+0

@ user2310289我会在2小时内尝试。 – RussianVodka

回答

0

如果您的插座仍然打开我相信,读取决不会retun -1。您不要关闭传输(根据文件没有达到EOF)。我相信当你的消息结束时(而不是-1),你的读取调用返回0。

Java文档: 读返回: *已被读取的字节指定数量, *基础流的读出方法返回-1,表明结束文件,或 *的可用的方法基础流返回零,表示进一步的输入请求会阻塞。

所以我相信你需要发送一个终止字符序列或你要发送的字符数,以便在客户端识别你的数据流内的数据块(消息)的边界。

+0

谢谢。查看更新的问题... 也许我可以在那里优化smth? – RussianVodka

+0

发送第一个2或4字节的消息字节数可以避免在接收到的每一串数据(平均复杂度为O(N))上执行字符串“#!EOF!#”的搜索)。使用消息的长度,您可以简单地使用读取的数据执行减法,从而了解消息何时结束(== 0)或其他消息已经在第一个(<0)之后。 希望这可以帮助你,祝你有美好的一天,斯特凡诺 –

0

我同意斯特凡诺。 PHP服务器端没有发生EOF或终止信号。 socket_write只是写$消息给客户端。如果你的意图是在整个消息写完后终止连接,那么你可能必须明确地使用socket_shutdown/socket_close。

你也可以尝试带标志的socket_send。这里是该文档http://www.php.net/manual/en/function.socket-send.php

+0

谢谢。我更新了这个问题。也许我可以优化那里? – RussianVodka