繁体   English   中英

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

[英]Send Byte array plus String over socket Java server to c++ client

我是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代码可以帮助您更好地理解我的问题。

对不起,我让你久等了。 已经有一段时间了,我需要自己检查一下。 我认为您正在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());

为什么不选择XML 您可以将任何类型的数据发送和接收到任何平台! 我觉得将是跨平台通信的最佳方法。

编辑

如果不能使用XML则可以使用ObjectInputStreamObjectOutputStream 通过使用此功能,您可以发送/接收对象。 这使您的生活更轻松。

似乎还不清楚,您的c端期望什么数据。 因此,尝试所有合理的可能性。 只是为了……。 clear:有两个ByteOrder:Little Endian和Big Endian。 Java始终使用Big Endian。 网络标准是Big Endian。 C使用本机的ByteOrder(取决于系统)。 在普通计算机上,这应该是Little Endian。 如果您的c端不进行解码或其他操作。 您需要将Java字节序手动转换为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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM