【问题标题】:Send Byte array then String then Byte over socket Java通过套接字 Java 发送字节数组,然后是字符串,然后是字节
【发布时间】:2014-07-04 09:01:37
【问题描述】:

我需要通过 Java 套接字向服务器发送一条文本消息,然后发送一个字节数组,然后发送一个字符串等... 到目前为止我开发的东西正在工作,但客户端设法只读取已发送的第一个字符串。

从服务器端:我使用BufferedOutputStream 发送字节数组,并使用PrintWriter 发送字符串。

问题是客户端和服务器不同步,我的意思是服务器发送字符串然后字节数组然后字符串而不等待客户端消耗每个需要的字节。

我的意思是场景不是这样的:

Server        Client 
Send String   read String
Send byte     read byte

但它是这样的:

Server        Client
Send String   
Send byte
Send String   
Send byte 

               read String   
               read byte
               read String   
               read byte

可能有用的是我确切知道每个字符串的大小和要读取的每个字节数组。

下面是分别用于发送字符串和字节数组的方法:

   // Send String to Client
    // --------------------------------------------------------------------
    public  void sendStringToClient (
                         String response, 
                         PrintWriter output) {
    try {
        output.print(response); 
        output.flush();

    } catch(Exception e) {
        e.printStackTrace();
    }
    System.out.println("send Seeder String : " + response);
    }

    // Send Byte to Client
    // --------------------------------------------------------------------
    public  void sendByteToClient (
                           byte[] response, 
                           BufferedOutputStream output) {
    try {
        output.write(response, 0, response.length); 
        //System.out.println("send : " + response);
    } catch (IOException e) {
        e.printStackTrace();
    }
    }

下面是分别用于读取字符串和字节数组的方法:

 public byte[] readInByte(int size) {

byte[] command = new byte[size];    
try {
    this.inByte.read(command);
} catch (IOException e) {
    e.printStackTrace();
}
return command;
}

public String readInString(int size) {
char[] c = new char[size];
try{
    this.inString.read(c, 0, size);
} catch (IOException e) {
    e.printStackTrace();
}
return String.valueOf(c);
}

【问题讨论】:

  • 我们可以看到您用于实现此目的的客户端和服务器代码吗?
  • @publ1c_stat1c 看看上面的代码。thks
  • @mitchellZ,...我有和你一样的情况。那么你现在怎么解决呢?
  • @gumuruh 我所做的是使用字符串数据和字节数据之间的分隔符将所有内容作为字节数组发送,在客户端我逐字节读取,每当我找到分隔符时我就会知道如果我必须以字符串或字节的形式读取缓冲区上的数据...顺便说一句,我尝试使用可序列化对象通过同一个套接字发送字符串和字节数组,但这非常慢(您可能已经知道)。祝你好运!

标签: java string sockets byte


【解决方案1】:

我真的很想将数据转换为 JSON 格式并通过 http 进行管道传输。您可以获得很多好处,包括为地球上几乎所有平台提供现成的 http 服务器和客户端,以及 JSON 互操作,更不用说所有内置的错误处理和恢复处理。

缺点是 http 和 JSON 编码的额外开销。您没有提到这是 UDP 还是 TCP 套接字,因此如果您尝试无连接,这可能是一个额外的缺点。

【讨论】:

  • 我正在使用tcp socket,实际上它是一个对等文件共享应用程序,其中所有对等通信消息都是文本,除了文件共享的二进制日期(不应该转换为字符串并且有作为字节数组发送)
【解决方案2】:

可能有用的是我确切地知道要读取的每个字符串的大小以及要读取的每个字节数组的大小。

没错。这非常很常见。基本上,您为每条消息添加长度前缀 - 您可能希望提供比这更多的标头信息(例如,它是字符串还是字节数组消息)。

您可以将消息长度(始终以字节为单位)表示为固定数量的字节(例如 4,假设您永远不需要超过 4GB 的消息)或使用 7 位编码整数(发送 7 位每个字节的长度,最高位只是表示这是否是长度的最后一个字节)。

一旦确定了消息长度,您就基本设置好了 - 您已经有效地将数据划分为自描述块。任务完成。

(顺便说一句,我会避免使用PrintWriter,因为它具有吞咽异常的性质。不过,一旦你这样做了,你实际上并不需要编写器,因为你可能想要转换每个@ 987654322@ 无论如何都放入一个字节数组中,在发送之前以字节为单位计算其长度。记得指定编码!)

【讨论】:

  • @keyser:这是 2^32,因此您可以指定的最大长度为 4 个字节。当然,您需要做一些工作来处理 Java 使用带符号整数的事实才能达到 2GB 以上。
猜你喜欢
  • 2013-06-30
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多