首页 新闻 会员 周边

Android Socket怎么和C++的服务端通信

0
悬赏园豆:30 [待解决问题]

这几天做一个项目,Socket服务端是C++写的,这几天用了好多办法,平常用的那些socket发送数据的方法都行不通

C++服务端是用结构体写的,但是我看了Java是没有结构体的,我看了java是没有结构体的,这怎么弄,我不懂C++的

我先服务端定义发一下

// 用户登录相关协议
 struct 
   {
   char UserName[12];
   char Password[18];
   char PhoneNum[12];
   }ReqUserLog;
       struct 
   {
   int UserID;
   int ErrCode;
   }ReqUserLogResult;

android 客户端该怎样写socket和接收呢?
我叫人C++服务端的人写了一个java例子给我,他发了一个方法给我,但是我看到这个方法还是不知道怎么用

private byte[] buildNetSendData(HashMap<Integer, Long> sendData, String vin) {
       ByteBuffer bytesBuf = ByteBuffer.allocate(sendData.size() * 12 + 18);

       Iterator iter = sendData.entrySet().iterator();
       while (iter.hasNext()) {
           Map.Entry<Integer, Long> entry = (Map.Entry<Integer, Long>) iter
                     .next();
           bytesBuf.putInt(entry.getKey());
           bytesBuf.putLong(entry.getValue());

       }
       byte[] data = new byte[sendData.size() * 12];
       System.arraycopy(bytesBuf.array(), 0, data, 0, data.length);
       bytesBuf.clear();
       byte[] data_en = new byte[data.length];
       int n = data.length / 12;
       String v_s = vin.substring(vin.length() - 12, vin.length());
       StringBuilder sb = new StringBuilder();
       for (int i = 0; i < n; i++) {
           sb.append(v_s);
       }
       String v_pwd = sb.toString();
       byte[] v_pwdbytes = v_pwd.getBytes();
       if (data.length == v_pwdbytes.length) {
           for (int i = 0; i < data.length; i++) {
                data_en[i] = (byte) (data[i] ^ v_pwdbytes[i]);
           }
       }
       bytesBuf.put(vin.getBytes());
       bytesBuf.put((byte) 0x01);
       bytesBuf.put(data_en);
       bytesBuf.flip();
       return bytesBuf.array();
     }

请各位知道的帮忙一下,这个socket该怎么写,最好有个发送和接收的例子

非常感谢

这是文档协议

协议ID

类型

长度

备注

ID = 0d22000

int

1

用户登录信息指令

UserName

Char

12

用户名

Password

Char

18

密码

PhoneNum

Char

12

登录的手机号码

 

协议ID

类型

长度

备注

ID = 0d22001

int

1

保存用户注册信息返回结果

UserID

Int

1

用户ID(获取用户信息时用此ID做参数)

ErrCode

Int

1

0:成功

-1:用户名不存在

-2:密码错误

我这样写着,调不通,那个大神看看,我哪里写错了

我这样写,为什么还是不行

定义一个类

package com.homemonitor.model.struct;

public class Login_Info{


public static int length = 33;

private byte[] buf = new byte[1 + 12 + 18 + 12];

public int cmdId = 0;

public String userName = "";

public String password = "";

public String phoneNum = "";

/* 构造并转换 */
public Login_Info(int cmdId, String userName, String password, String phoneNum) {

this.cmdId = cmdId;
this.userName = userName;
this.password = password;
this.phoneNum = phoneNum;

byte[] temp = toLH(cmdId);
System.arraycopy(temp, 0, buf, 20, temp.length);

temp = userName.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length);

temp = password.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length);

temp = phoneNum.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length);
}

private static String toStr(byte[] valArr, int startpoint, int maxLen) {
int index = 0;
while (index + startpoint < valArr.length && index < maxLen) {
if (valArr[index + startpoint] == 0) {
break;
}
index++;
}
byte[] temp = new byte[index];
System.arraycopy(valArr, startpoint, temp, 0, index);
return new String(temp);
}

public static String get_login_info(byte[] bArr) {
int id = 0;
int userId = 0;
int errCode = 0;

byte[] temp = new byte[3];

id = vtolh(bArr);

System.arraycopy(bArr, 1, temp, 0, 1);
userId = vtolh(temp);

System.arraycopy(bArr, 2, temp, 0, 3);
errCode = vtolh(temp);

return "id=" + id + ",userId=" + userId + "," + "errCode=" + errCode;
}

protected 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;
}

/**
* 将低字节在前转为int,高字节在后的byte数组
*/
protected static int vtolh(byte[] bArr) {
int n = 0;
for(int i=0;i<bArr.length&&i<4;i++){
int left = i*8;
n+= (bArr[i] << left);
}
return n;
}

/* 返回要发送的数组 */
public byte[] getBuf() {
return buf;
}
}

调用

try {
InetSocketAddress = new InetSocketAddress("120.25.246.140", 5000);
Socket socket_client = new Socket();
socket_client.connect(addr);

if (client_socket == null)
return;

int available = 0;
Login_Info sendmsg = new Login_Info(22000, "hello", "123456", "18088881111");

byte[] receive = new byte[3];
int available = 0;
Login_Info sendmsg = new Login_Info(cmd, userName, password, phoneNum);
try {
if ((available = socket.getInputStream().available()) >= 0)
{
socket.getInputStream().read(new byte[available]);
socket.getInputStream().skip(available);
}
socket.getOutputStream().write(sendmsg.getBuf());
socket.getOutputStream().flush();
socket.getInputStream().read(receive);
String result = Login_Info.get_login_info(receive);

}
catch (IOException e) {
e.printStackTrace();
}
}
catch (Exception ex) {
System.out.println("ex===" + ex.getMessage());
}

进攻是最好的防守的主页 进攻是最好的防守 | 初学一级 | 园豆:23
提问于:2015-06-18 21:52
< >
分享
所有回答(4)
0

...这个东西关结构体什么事儿?

通讯传输的都是二进制数据,这么怎么编码的,那边怎么解码不就可以了...

吴瑞祥 | 园豆:29449 (高人七级) | 2015-06-19 07:26
0

我按照你最后给的文档协议来回答:

ByteBuffer bytesBuf = ByteBuffer.allocate(sizeof(int) + 12 + 18 + 12);

bytesBuf.PutInt(0x0d22000); // 用户登录信息指令,没考虑网络字节序和主机字节序的问题,你需要同他们确定。

bytesBuf.("User".getBytes()); // 用户名,假设为 unicode 双字节编码,同时 "User" 长度小于 12 字节。

bytesBuf.("Pwd".getBytes()); // 密码,假设为 unicode 双字节编码,同时 "Pwd" 长度小于 18 字节。

bytesBuf.("Phone".getBytes()); // 手机号,假设为 unicode 双字节编码,同时 "Phone" 长度小于 12 字节。

 

Socket.Send(bytesBuf.Array()); // 发送登录数据包

 

PS: 我不知道这个协议是否描述完整,一般来说需要对数据作封包设计,也就是上面的数据只是包体,包体前一般有 4  个字节来表示包体的长度。

 

 

Launcher | 园豆:45045 (高人七级) | 2015-06-19 09:28

我这样写,为什么还是不行

定义一个类

package com.homemonitor.model.struct;

public class Login_Info{


public static int length = 33;

private byte[] buf = new byte[1 + 12 + 18 + 12];

public int cmdId = 0;

public String userName = "";

public String password = "";

public String phoneNum = "";

/* 构造并转换 */
public Login_Info(int cmdId, String userName, String password, String phoneNum) {

this.cmdId = cmdId;
this.userName = userName;
this.password = password;
this.phoneNum = phoneNum;

byte[] temp = toLH(cmdId);
System.arraycopy(temp, 0, buf, 20, temp.length);

temp = userName.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length);

temp = password.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length);

temp = phoneNum.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length);
}

private static String toStr(byte[] valArr, int startpoint, int maxLen) {
int index = 0;
while (index + startpoint < valArr.length && index < maxLen) {
if (valArr[index + startpoint] == 0) {
break;
}
index++;
}
byte[] temp = new byte[index];
System.arraycopy(valArr, startpoint, temp, 0, index);
return new String(temp);
}

public static String get_login_info(byte[] bArr) {
int id = 0;
int userId = 0;
int errCode = 0;

byte[] temp = new byte[3];

id = vtolh(bArr);

System.arraycopy(bArr, 1, temp, 0, 1);
userId = vtolh(temp);

System.arraycopy(bArr, 2, temp, 0, 3);
errCode = vtolh(temp);

return "id=" + id + ",userId=" + userId + "," + "errCode=" + errCode;
}

protected 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;
}

/**
* 将低字节在前转为int,高字节在后的byte数组
*/
protected static int vtolh(byte[] bArr) {
int n = 0;
for(int i=0;i<bArr.length&&i<4;i++){
int left = i*8;
n+= (bArr[i] << left);
}
return n;
}

/* 返回要发送的数组 */
public byte[] getBuf() {
return buf;
}
}

调用

try {
InetSocketAddress = new InetSocketAddress("120.25.246.140", 5000);
Socket socket_client = new Socket();
socket_client.connect(addr);

if (client_socket == null)
return;

int available = 0;
Login_Info sendmsg = new Login_Info(22000, "hello", "123456", "18088881111");

byte[] receive = new byte[3];
int available = 0;
Login_Info sendmsg = new Login_Info(cmd, userName, password, phoneNum);
try {
if ((available = socket.getInputStream().available()) >= 0)
{
socket.getInputStream().read(new byte[available]);
socket.getInputStream().skip(available);
}
socket.getOutputStream().write(sendmsg.getBuf());
socket.getOutputStream().flush();
socket.getInputStream().read(receive);
String result = Login_Info.get_login_info(receive);

}
catch (IOException e) {
e.printStackTrace();
}
}
catch (Exception ex) {
System.out.println("ex===" + ex.getMessage());
}

支持(0) 反对(0) 进攻是最好的防守 | 园豆:23 (初学一级) | 2015-06-19 23:11
0

1楼已经说得很明白了。再告诉你一个好用的框架 protobuf

angelshelter | 园豆:9887 (大侠五级) | 2015-06-19 17:24
0

自己解决了

进攻是最好的防守 | 园豆:23 (初学一级) | 2015-06-22 22:18
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册