通过套接字Java发送字节数组、字符串和字节

通过套接字Java发送字节数组、字符串和字节,java,string,sockets,byte,Java,String,Sockets,Byte,我需要通过Java套接字向服务器发送一条文本消息,然后发送一个字节数组和一个字符串等。。。 到目前为止,我所开发的功能仍在运行,但客户端只能读取发送的第一个字符串 从服务器端:我使用BufferedOutputStream发送字节数组,并使用PrintWriter发送字符串 问题是客户端和服务器不同步,我的意思是服务器先发送字符串,然后发送字节数组,然后发送字符串,而不等待客户端使用所需的每个字节 我的意思是,情况并非如此: Server Client Send String

我需要通过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);
}
以下是分别用于读取字符串和字节数组的方法:

   // 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);
}
可能有用的是,我确切地知道要读取的每个字符串和要读取的每个字节数组的大小

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

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

一旦您确定了消息长度,您就基本上完成了设置——您已经有效地将数据流划分为自描述块。工作完成了

(顺便说一句,我不想使用
PrintWriter
,因为它会吞噬异常。但一旦这样做了,您实际上就不需要编写器,因为您可能希望将每个
字符串
转换为字节数组,以便在发送之前以字节为单位计算其长度。请记住指定编码!)

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

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

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

一旦您确定了消息长度,您就基本上完成了设置——您已经有效地将数据流划分为自描述块。工作完成了

(顺便说一句,我不想使用
PrintWriter
,因为它会吞噬异常。但一旦这样做了,您实际上就不需要编写器,因为您可能希望将每个
字符串
转换为字节数组,以便在发送之前以字节为单位计算其长度。请记住指定编码!)

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

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

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

一旦您确定了消息长度,您就基本上完成了设置——您已经有效地将数据流划分为自描述块。工作完成了

(顺便说一句,我不想使用
PrintWriter
,因为它会吞噬异常。但一旦这样做了,您实际上就不需要编写器,因为您可能希望将每个
字符串
转换为字节数组,以便在发送之前以字节为单位计算其长度。请记住指定编码!)

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

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

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

一旦您确定了消息长度,您就基本上完成了设置——您已经有效地将数据流划分为自描述块。工作完成了


(顺便说一句,我不想使用
PrintWriter
,因为它会吞噬异常。但一旦这样做了,您实际上就不需要编写器,因为您可能希望将每个
字符串
转换为字节数组,以便在发送之前以字节为单位计算其长度。请记住指定编码!)

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

缺点是http和JSON编码的额外开销。您没有提到这是UDP还是TCP套接字,所以如果您试图进行欺骗,这可能是一个额外的缺点