通过socket Java服务器将字节数组加字符串发送到c++;客户 我是java新手,编写代码java服务器与C++客户端通信 服务器将从客户端读取消息,并以相同的格式做出相应的响应。 信息的格式为: 以下示例显示385字节消息的编码。请注意,传输的总字节数为389(4字节长度+消息正文)

通过socket Java服务器将字节数组加字符串发送到c++;客户 我是java新手,编写代码java服务器与C++客户端通信 服务器将从客户端读取消息,并以相同的格式做出相应的响应。 信息的格式为: 以下示例显示385字节消息的编码。请注意,传输的总字节数为389(4字节长度+消息正文),java,Java,0x00 0x00 0x01 0x81 |[消息内容]消息长度(4 字节)|消息正文(385字节) 用C++编写,服务器用java编写。 虽然java服务器能够从客户端读取消息,但无法以正确的格式发送到响应,因为客户端无法在它们之间通信失败 JAVA代码: DataInputStream in = new DataInputStream (server.getInputStream()); PrintStream out = new PrintStream(server.getOutputStr

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')) 

这是一个运行良好的函数,上面所写的是我的,不是用java编写的。我也试过你的建议,但没能做到。希望这段python代码能帮助您更好地理解我的问题。

对不起,我让您久等了。已经有一段时间了,我需要亲自检查一下。IM认为你正在正确解码一个整数组成的4字节在C++结束。 那么这应该是可行的:

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使用大的EnDead,这是网络的字节序,C++使用小的字节序。并将其用作整数。最好将其解释为有符号整数,但如果将其解释为无符号整数,则应该没有问题

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


为什么不选择
XML
?您可以向任何平台发送和接收任何类型的数据!我认为这是跨平台沟通的最佳方式

编辑


如果不能使用
XML
,则可以使用
ObjectInputStream
ObjectOutputStream
。通过使用它,您可以发送/接收对象。这会让你的生活更轻松。

看来,你的c端需要什么样的数据还不是很清楚。所以,尝试每一种合理的可能性。只是想澄清一下:字节顺序有两种:小字节和大字节。Java总是使用Big-Endian。网络标准是Big-Endian。C使用本机字节顺序(取决于系统)。在普通机器上,这应该是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);

你不可能用你提供的代码回答这个问题。我猜你的请求是字符串。在java中,字符有2个字节。这是可能发生的第一个问题。您真的应该使用一些字节缓冲符来正确编码您的消息。@xeed,您的意思是我必须将所有消息转换成字节。我也尝试过:byte[]breqmsgtosent=(String.format(“%08x”,msglen)+reqmsgtosent).getBytes(Charset.forName(“UTF-8”);并使用DataOutputStream将消息发送到客户端,但失败。让我们从String.format(“%08x”,msglen)开始。这不是发送?int?的4个字节?。它将每个数字转换为一个字符,因此可以得到8个甚至16个字节。使用ByteBuffer将整数转换为字节。我不能使用xml,因为无法更改客户端。在java中实现服务器是需要的。Junaid,我的问题是C++应用程序是C++的,它的端部必须有结构。所以,我必须发送4个字节(包含消息其余部分的长度)+消息的字符串长度定义为4个字节。有没有什么方法可以在我的套接字上发送消息一次完成。这应该可以工作。有三件事,你可能需要注意:-Java是按网络字节顺序工作的(所以你不需要改变它)-你可能在解码无符号整数,这在这个维度上应该无关紧要-字符串编码可能是错误的,但是utf-8和ascii编码对于这些字符来说是相同的。您需要向我们展示C++侧,给您一个解决方案,我尝试了您的代码,但在客户端,它显示长度为零,不处理进一步的消息。我现在没有C++代码。这是一座8年前建成的老图书馆。这就是我与您共享python代码的原因,该代码运行良好。这对你没有帮助吗?嗯,我不擅长python。但是第二行htonlMsgLen32=pack('L',htonlMsgLen)让我想知道,您是否使用的是长的o和整数。你试过了PUTRON部分吗?我试过了你建议的最新代码,但是在C++客户端仍然有零长度。我们可以使用以下代码实现htonl:ByteBuffer.allocate(4).putInt(x).order(ByteOrder.nativeOrder()).getInt(0);对于htonlMsgLen32,它只是将其转换为十六进制。简而言之
//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);