通过套接字Java服务器将字节数组和字符串发送到c ++客户端

时间:2015-01-16 11:08:00

标签: java

我是java新手并编写java服务器与c ++客户端通信的代码 服务器将从客户端读取消息并以相同的格式进行相应的响应。 消息将采用以下格式: 以下示例显示了385字节消息的编码。请注意,传输的总字节数为389 (4 byte length + message body)

  

0x00 0x00 0x01 0x81 | [消息内容]消息长度(4   字节)|消息正文(385字节)

客户端是用C ++编写的,服务器是用java编写的。

虽然java服务器能够从客户端读取消息但无法以正确的格式发送到响应,因为哪个客户端之间无法通信失败。

JAVA代码:

DataInputStream in = new DataInputStream (server.getInputStream());
PrintStream out = new PrintStream(server.getOutputStream(),true,"UTF-8");


while((incummsg = in.readLine()) != null && !incummsg.equals(".")) {
  mtype=sample_server.mType(incummsg);
  System.out.println("\nGateway msg:"+incummsg);
  if(sample_server.MsgMapping.get(mtype)!=null){
      reqmsgtosent=sample_server.getRequiredMsg(incummsg, mtype);
      msglen=reqmsgtosent.length();
      System.out.println("\nMsg_len:"+msglen);
      int htnolmsglen = sample_server.htonl(msglen);
      out.println(String.format("%08x",msglen)+reqmsgtosent);
      }
}

感谢@xeed的帮助,但它仍然不适合我。我在python中有一个代码,对我来说很好。我想在java中重写它,但无法这样做。 Python代码:

def SendMsg(self, msg):

    htonlMsgLen = socket.htonl(len(msg))

    htonlMsgLen32 = pack('L', htonlMsgLen)

    lenofSentMsg = self.request.send(htonlMsgLen32)

    lenofSentMsg = self.request.send(msg.encode('utf-8')) 

这是函数whihc正常工作,上面写的是我的,这在java中不起作用。我也尝试了你的建议,但无法做到。愿这个python代码帮助你更好地理解我的问题。

3 个答案:

答案 0 :(得分:0)

抱歉,我让你久等了。已经有一段时间了,我需要自己检查一下。我认为你在c ++端正确解码了一个由4个字节组成的整数。 然后这应该工作:

String msg = "Hello World!";
ByteBuffer bytebuffer = ByteBuffer.allocate(msg.getBytes().length+Integer.SIZE/8);
bytebuffer.putInt(msg.getBytes().length);
bytebuffer.put(msg.getBytes());
server.getOutputStream().write(bytebuffer.array());

但我几乎可以肯定有更好的方法。我相信有一种方法,它结合了ByteBuffer的put功能和OutputStream功能。

编辑:稍作修改。我在一个旧的源头挖掘了这个:

String data = "Hello World!";
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(data.length());
mSocketSend.getOutputStream().write(b.array());
final PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(),false);
pw.print(data);
pw.flush();

请记住以下几点。要使其在c ++端工作,需要从套接字读取4个字节的数据。反转字节顺序,因为java使用big endian,这是网络字节顺序,c ++使用little endian。并将其用作整数。最好将其解释为有符号整数,但如果它被解释为无符号则应该没问题。

另一个编辑: 只是为了确保,你不是在等待很长时间(8个字节),请尝试

ByteBuffer b = ByteBuffer.allocate(8);
b.putLong(data.length());

答案 1 :(得分:0)

为什么你不去XML?您可以向任何平台发送和接收任何类型的数据!我认为thisthis是跨平台沟通的最佳方法。

修改

如果您无法前往XML,则可以使用ObjectInputStreamObjectOutputStream。通过使用它,您可以发送/接收对象。这会让你的生活更轻松。

答案 2 :(得分:0)

看起来,它并不是很清楚,你的c方期待的数据是什么。所以尝试一切合理的可能性。只是为了做某事明确:有两个ByteOrders:Little Endian和Big Endian。 Java总是使用Big Endian。网络标准是Big Endian。 C使用本机ByteOrder(取决于系统)。在普通机器上,这应该是Little Endian。 如果你的c方没有解码或某事。您需要手动将java byteorder转换为little endian。这就是你的python代码所做的事情。您应该能够使用ByteOrder.native()代替。只需检查LITTLE_ENDIAN和native()的值是否相同。

//Short
short slength = (short)length
ByteBuffer b = ByteBuffer.allocate(2);
b.order(ByteOrder.BIG_ENDIAN);
b.putShort(slength);

ByteBuffer b = ByteBuffer.allocate(2);
b.order(ByteOrder.LITTLE_ENDIAN);
b.putShort(slength);

//Int
int ilength = (int) length
ByteBuffer b = ByteBuffer.allocate(4);
b.order(ByteOrder.BIG_ENDIAN);
b.putInt(ilength);

//This is the one, which should work, if everything you say is true
ByteBuffer b = ByteBuffer.allocate(4);
b.order(ByteOrder.LITTLE_ENDIAN);
b.putInt(ilength);

 //Long
long llength = (long) length;
ByteBuffer b = ByteBuffer.allocate(8);
b.order(ByteOrder.BIG_ENDIAN);
b.putLong(llength);

ByteBuffer b = ByteBuffer.allocate(8);
b.order(ByteOrder.LITTLE_ENDIAN);
b.putLong(llength);