简体   繁体   中英

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. The message will be in format : The following example shows the encoding of a 385-byte message. Note that the total number of bytes transmitted is 389 (4 byte length + message body) .

0x00 0x00 0x01 0x81 | [Message Content] Message Length (4 Bytes) | Message Body (385 Bytes)

The client is written in C++ and server is in 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 Code:

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. I have a code in python which is working fine for me. I wanted to rewrite it in java but unable to do so. Python Code:

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. I tried your suggestion too but unable to make do it. May this python code help you understand my problem in better way.

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. 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.

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. Reverse the byte order, since java uses big endian, which is the network byteorder and c++ uses 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

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

Why you don't go for 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 . 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. So try out every reasonably possibility. Just to make sth. clear: There are two ByteOrders: Little Endian and Big Endian. Java uses always Big Endian. The Networking standard is Big Endian. C uses the native ByteOrder (depending on the system). On normal machines this should be Little Endian. If your c side does no decoding or sth. You need to convert the java byteorder manually to little endian. Infact that is what your python code does. You should be able to use ByteOrder.native() instead. Just check if the values of LITTLE_ENDIAN and native() are the same.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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