我是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代码帮助你更好地理解我的问题。
答案 0 :(得分:0)
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
?您可以向任何平台发送和接收任何类型的数据!我认为this和this是跨平台沟通的最佳方法。
修改强>
如果您无法前往XML
,则可以使用ObjectInputStream
和ObjectOutputStream
。通过使用它,您可以发送/接收对象。这会让你的生活更轻松。
答案 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);