Java与C++Socket通讯注意事项
原文链接: http://my.oschina.net/ypimgt/blog/106439
因为java发送的都是网络字节序(big-endium),而c++是主机字节序(little-endium),所以当消息中有整型,浮点型(应尽量避免使用)的时候需要用htonl,htons,ntohl,ntohs等函数转换一下,字符串由于是单字节排序的不需要转换,但应注意c++字符串是以'/0'作为结束符的,如果找不到'/0'可能会出现一些乱码,所以接收的时候可以分配一个length+1的buffer用来接收消息.
举例:c++ server, java client,假设开发的是c++ server,那么:
java client--------->c++ server: c++ server需要调用ntohs,ntohl
c++ server--------->java client: c++ server需要调用htons,htonl
至于浮点型可以使用以下的函数转换:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
float tcp_htonf( float f)
{
unsigned char *p, p0, p1;
if (htons(1) ==1) return f;
p =(unsigned char *)&f;
p0 =p[0];
p1 =p[1];
p[0] =p[3];
p[3] =p0;
p[1] =p[2];
p[2] =p1;
return f;
}
float tcp_ntohf( float f)
{
unsigned char *p, p0, p1;
if (ntohs(1) ==1) return f;
p =(unsigned char *)&f;
p0 =p[0];
p1 =p[1];
p[0] =p[3];
p[3] =p0;
p[1] =p[2];
p[2] =p1;
return f;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
double tcp_htond( double d)
{
unsigned char *p, p0, p1, p2, p3;
if (htons(1) ==1) return d;
p =(unsigned char *)&d;
p0 =p[0];
p1 =p[1];
p2 =p[2];
p3 =p[3];
p[0] =p[7];
p[7] =p0;
p[1] =p[6];
p[6] =p1;??
p[2] =p[5];??
p[5] =p2;
p[3] =p[4];
p[4] =p3;
return d;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
double tcp_ntohd( double d)
{
unsigned char *p, p0, p1, p2, p3;
if (ntohs(1) ==1) return d;
p =(unsigned char *)&d;
p0 =p[0];
p1 =p[1];
p2 =p[2];
p3 =p[3];
p[0] =p[7];
p[7] =p0;
p[1] =p[6];
p[6] =p1;
p[2] =p[5];
p[5] =p2;
p[3] =p[4];
p[4] =p3;
return d;
}
|
java代码发送结构体
最近给个朋友做个网站的客户端,使用C/S模式,Client为VC6开发,Server为Java,通过Socket通信。由于Client这边为C++,所以,在接受Java发过来的数据包时,需要知道发来的包的长度,所以,就要引入变长包的机制。
方法是:首先Server发送一个包头,如下:
// packet head
typedef struct tagPacketHead{
long PacketID;
long PacketLen;
}PacketHead;
包头后面跟上包体,其中包体的长度,就是上面结构体中的PacketLen,Clinet首先接受包头,因为包头是两边约定好的,所以可以直接Receive一个定长的消息,也就是这个包头的长度的消息,从包头中取得包体的长度后,就可以再次Receive一个包体长度的消息了。那么Java中如何发送一个结构体呢?下面是解决方法:
package org.charry.org;
import java.net.*;
/**
*
* 字节转换,参考网络文章
*/
class Packet {
private byte[] buf = null;
/**
* 将int转为低字节在前,高字节在后的byte数组
*/
private static byte[] toLH(int n) {
byte[] b = new byte[4];
b[0] = (byte) (n & 0xff);
b[1] = (byte) (n >> 8 & 0xff);
b[2] = (byte) (n >> 16 & 0xff);
b[3] = (byte) (n >> 24 & 0xff);
return b;
}
/**
* 将float转为低字节在前,高字节在后的byte数组
*/
private static byte[] toLH(float f) {
return toLH(Float.floatToRawIntBits(f));
}
/**
* 构造并转换
*/
public Packet(int packetID, int packetLen, String packetBody) {
byte[] temp = null;
buf = new byte[packetBody.getBytes().length + 8];
temp = toLH(packetID);
System.arraycopy(temp, 0, buf, 0, temp.length);
temp = toLH(packetLen);
System.arraycopy(temp, 0, buf, 4, temp.length);
System.arraycopy(packetBody.getBytes(), 0, buf, 8,packetBody.length());
}
/**
* 返回要发送的数组
*/
public byte[] getBuf() {
return buf;
}
/**
* 发送测试
*/
public static void main(String[] args) {
try {
String tmp = “test string!”;
Socket sock = new Socket(”127.0.0.1″, 8888);
sock.getOutputStream().write(
new Packet(123, tmp.length(), tmp).getBuf());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
从Client端发到Server的数据就无须特殊处理了,Java的流可以很好的处理这些。
Java与C++Socket通讯注意事项相关推荐
- Java与C++Socket通讯注意
2019独角兽企业重金招聘Python工程师标准>>> c++与java进行socket通信时注意事项 因为java发送的都是网络字节序(big-endium),而c++是主机字节序 ...
- java安卓模拟器和电脑通信_Android 模拟器(JAVA)与C++ socket 通讯 分享
C++ 作为Client端 view plaincopy to clipboardprint? // Client.cpp : Defines the entry point for the cons ...
- socket通讯工具类
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- java与 C++ 之间进行 SOCKET 通讯要点简要解析
Endian定义: 在计算机系统体系结构中用来描述在多字节数中各个字节的存储顺序. big-endian也称高位在前.大端在前.是 计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最重要字节 ...
- as3 java 交互_求大佬用 Java 实现这段 AS3 的 socket 通讯功能
最近在分析一个直播网站,初步分析后发现是在 swf 中用 socket 通讯返回的 flv 地址. 其中 Actionscript socket 通讯的关键代码如下: this._socket = n ...
- Socket网络通讯开发总结之:Java 与 C进行Socket通讯
先交待一下业务应用背景: 服务端:移动交费系统:基于C语言的Unix系统 客户端:增值服务系统:基于Java的软件系统 通迅协议:采用TCP/IP协议,使用TCP以异步方式接入 数据传输:基于Sock ...
- socket java 服务器端_Java 简单的Socket通讯的服务器端实现
最近学安卓开发,看到书上这个Socket通讯的实例,按照书上打的时候客户端一直连接不上,可能是网络问题或者虚拟机连接问题,所以就用控制台实现的客户端,这里是服务器端的.话不多说,直接贴代码 impor ...
- java socket通讯_Java socket通讯实现过程及问题解决
这篇文章主要介绍了Java socket通讯实现过程及问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本来是打算验证java socket是 ...
- java socket 卡住_Java socket通讯实现过程及问题解决
这篇文章主要介绍了java socket通讯实现过程及问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本来是打算验证java socket是 ...
最新文章
- 图灵访谈 | 微盟技术专家戴頔:永远行走在路上
- java静态分派_Java基础——重载、静态分派与动态分派
- java中main方法前的public static void及其后面的(String[] args)【笔记自用】
- pyqt5从子目录加载qrc文件_【JVM系统学习之路】一篇看懂类加载
- CentOS6.5下搭建SVN服务器
- 互联网前景如何,还值得进入嘛?
- js和ajax点赞功能代码_Redis实现点赞功能模块,你了解多少?
- 编写一个java小程序输出学生姓名在Unicode表中的位置
- 基于SNMP网络管理系统的实现
- 模糊查询SqlParameter参数化like
- 智能电销机器人语音自动外呼效果好吗
- 空间平面方程的三种表述方式
- 做跨境电商,用信用卡通道还是Paypal收款比较便宜?
- 谷歌商店上架APP被拒绝
- 英文文献翻译成中文,推荐哪个软件?
- 教你长高 男的没有1米8的 女的没1.65都要看啊
- 【开源项目】Flutter版 玩安卓,android开发模拟器推荐
- vscode多行注释,自定义按键多行注释
- Android:下载图片
- 100层楼和两个玻璃球
热门文章
- 用上GAN的推荐算法成精了,看完视频马上刷出相关文章丨KDD 2021
- 他失明40年,只因戴上了这副护目镜,现在竟能数清斑马线 | Nature子刊
- 如果让AI根据文字画「抽象画」,那得成什么样?|DeepMind新算法
- 我在上海的AI新地标,看懂了明略的游戏规则
- 两年伯克利数学博士毕业,蝉联阿里数学竞赛金奖,张钺:我就是个普通人
- 意念实时转语音!Facebook的非植入式脑机接口,解码准确率达到76%
- java 打包的两种方式
- Django1.11模型使用
- PHP 页面编码声明方法详解(header或meta)
- 【第二组】项目冲刺(Beta版本)第六次每日例会 2017/7/24