简体   繁体   English

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

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

I am new to java and writing the code the java server to communicate with c++ client The server will read the message from the client and respond correspondingly in the same format. 我是java的新手,正在编写Java服务器与c ++客户端通信的代码。服务器将从客户端读取消息,并以相同的格式进行相应的响应。 The message will be in format : The following example shows the encoding of a 385-byte message. 该消息将采用以下格式:以下示例显示了385字节消息的编码。 Note that the total number of bytes transmitted is 389 (4 byte length + message body) . 请注意,传输的字节总数为389 (4 byte length + message body)

0x00 0x00 0x01 0x81 | 0x00 0x00 0x01 0x81 | [Message Content] Message Length (4 Bytes) | [消息内容]消息长度(4个字节)| Message Body (385 Bytes) 邮件正文(385字节)

The client is written in C++ and server is in java. 客户端用C ++编写,服务器用Java编写。

Although java server is able to read the message from the client but unable to send to response in the correct format due to which client unable to communication fail between them. 尽管java服务器能够从客户端读取消息,但由于客户端之间无法通信而无法以正确的格式发送响应。

JAVA Code: 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);
      }
}

Thanks @xeed for th ehelp but it is still not working for me. 感谢@xeed的帮助,但它仍然对我不起作用。 I have a code in python which is working fine for me. 我在python中有一个代码对我来说很好。 I wanted to rewrite it in java but unable to do so. 我想用Java重写它,但无法这样做。 Python Code: 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')) 

this is the function whihc is working fine and above written is mine which is not working in java. 这是whihc正常工作的函数,上面写的是我的在Java中不工作的函数。 I tried your suggestion too but unable to make do it. 我也尝试过您的建议,但无法做到。 May this python code help you understand my problem in better way. 也许这段python代码可以帮助您更好地理解我的问题。

Sorry, i kept you waiting. 对不起,我让你久等了。 Its been a while and I needed to check in on that myself. 已经有一段时间了,我需要自己检查一下。 Im thinking that you are properly decoding an integer consisting of 4 bytes at c++ end. 我认为您正在c ++末尾正确解码由4个字节组成的整数。 Then this should work: 然后这应该工作:

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());

But I'm almost certain that there is a better way. 但我几乎可以肯定,还有更好的方法。 I believe there is a method, which combines the put functionality of the ByteBuffer and the OutputStream functionality. 我相信有一种方法,它结合了ByteBuffer的put功能和OutputStream功能。

Edit: A little alteration. 编辑:一点改动。 I digged this up in an old source of mine: 我在一个古老的矿山中挖了这个:

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();

Keep the following in mind. 请记住以下几点。 To get this to work the c++ side, needs to read 4 bytes of data from the socket. 为了使此功能在c ++方面起作用,需要从套接字读取4个字节的数据。 Reverse the byte order, since java uses big endian, which is the network byteorder and c++ uses little endian. 反转字节顺序,因为java使用big endian,这是网络字节顺序,而c ++使用little endian。 and use this as an integer. 并将其用作整数。 It would be best to interpret it as a signed integer, but it should be no problem, if it is interpreted as unsigned. 最好将其解释为有符号整数,但如果将其解释为无符号整数,则应该没有问题。

another Edit: Just to make sure, you are not waiting for a long(8 bytes), try 另一个编辑:只是为了确保您没有等待很长的时间(8个字节),请尝试

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

Why you don't go for XML ? 为什么不选择XML You can send and receive any type of data to any platform ! 您可以将任何类型的数据发送和接收到任何平台! I think this and this would be the BEST approach for cross platform communication. 我觉得将是跨平台通信的最佳方法。

Edit 编辑

If you cannot go for XML then you can use ObjectInputStream and ObjectOutputStream . 如果不能使用XML则可以使用ObjectInputStreamObjectOutputStream By using this you can send/receive Objects. 通过使用此功能,您可以发送/接收对象。 This make your life easier. 这使您的生活更轻松。

It appears, that its not really clear, what data your c side is expecting. 似乎还不清楚,您的c端期望什么数据。 So try out every reasonably possibility. 因此,尝试所有合理的可能性。 Just to make sth. 只是为了……。 clear: There are two ByteOrders: Little Endian and Big Endian. clear:有两个ByteOrder:Little Endian和Big Endian。 Java uses always Big Endian. Java始终使用Big Endian。 The Networking standard is Big Endian. 网络标准是Big Endian。 C uses the native ByteOrder (depending on the system). C使用本机的ByteOrder(取决于系统)。 On normal machines this should be Little Endian. 在普通计算机上,这应该是Little Endian。 If your c side does no decoding or sth. 如果您的c端不进行解码或其他操作。 You need to convert the java byteorder manually to little endian. 您需要将Java字节序手动转换为little endian。 Infact that is what your python code does. 实际上,这就是您的python代码所做的。 You should be able to use ByteOrder.native() instead. 您应该可以改用ByteOrder.native()。 Just check if the values of LITTLE_ENDIAN and native() are the same. 只需检查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