Java和c++的Socket通信如何发送结构体?

spaceman10 2014-07-01 01:47:32
我这边的c++程序即时服务端,又是客户端,应该如何接收和打包结构体给java端?
struct A
{
int id;
string msg;
};
...全文
581 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
梦想照旧实现 2014-07-03
  • 打赏
  • 举报
回复
引用 8 楼 spaceman10 的回复:
[quote=引用 6 楼 swgshj 的回复:] 底层通讯的send和recv函数应该都是面向字节流的。 把struct A { int id; string msg; }; 修改为 struct A { int id; char msg[MAX_LEN]; }; 假设 A是字节对齐的 //C++侧发送 A a; a.id=0x12; strcpy(a.msg, "hello"); //a.msg = "hello" 发送函数为send(sockid, &a, (sizeof(a,id) + strlen(a.msg))); 那么实际你发送出去的字节流为(十六进制): 12 00 00 00 68 65 6c 6c 6f 小端0x12 'h' 'e' 'l' 'l' 'o' //Java侧接收, 你使用java的接受函数,收到的也是字节流 12 00 00 00 68 65 6c 6c 6f
c++接受段要怎么弄啊?[/quote] 你是在windows下开发还是linux下?Socket没接触过吗?
赵4老师 2014-07-02
  • 打赏
  • 举报
回复
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
赵4老师 2014-07-02
  • 打赏
  • 举报
回复
引用 14 楼 yangyunzhao 的回复:
[quote=引用 13 楼 spaceman10 的回复:] 我直接用memcpy把接收到的bufffer拷到相应结构体里,再发出去竟然可以了,我都不知道这样子会不会有问题?
注意字节对齐[/quote]
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD  { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1  { int a; char b[13]; double c;};
#pragma pack(2)
struct A2  { int a; char b[13]; double c;};
#pragma pack(4)
struct A4  { int a; char b[13]; double c;};
#pragma pack(8)
struct A8  { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
    printf("AD.a %d\n",field_offset(AD,a));
    printf("AD.b %d\n",field_offset(AD,b));
    printf("AD.c %d\n",field_offset(AD,c));
    printf("\n");
    printf("A1.a %d\n",field_offset(A1,a));
    printf("A1.b %d\n",field_offset(A1,b));
    printf("A1.c %d\n",field_offset(A1,c));
    printf("\n");
    printf("A2.a %d\n",field_offset(A2,a));
    printf("A2.b %d\n",field_offset(A2,b));
    printf("A2.c %d\n",field_offset(A2,c));
    printf("\n");
    printf("A4.a %d\n",field_offset(A4,a));
    printf("A4.b %d\n",field_offset(A4,b));
    printf("A4.c %d\n",field_offset(A4,c));
    printf("\n");
    printf("A8.a %d\n",field_offset(A8,a));
    printf("A8.b %d\n",field_offset(A8,b));
    printf("A8.c %d\n",field_offset(A8,c));
    printf("\n");
    printf("A16.a %d\n",field_offset(A16,a));
    printf("A16.b %d\n",field_offset(A16,b));
    printf("A16.c %d\n",field_offset(A16,c));
    printf("\n");
    return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//
yangyunzhao 2014-07-01
  • 打赏
  • 举报
回复
引用 13 楼 spaceman10 的回复:
我直接用memcpy把接收到的bufffer拷到相应结构体里,再发出去竟然可以了,我都不知道这样子会不会有问题?
注意字节对齐
spaceman10 2014-07-01
  • 打赏
  • 举报
回复
我直接用memcpy把接收到的bufffer拷到相应结构体里,再发出去竟然可以了,我都不知道这样子会不会有问题?
yangyunzhao 2014-07-01
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
需要处理半包和粘包问题
cjzzmdn 2014-07-01
  • 打赏
  • 举报
回复
gsoap不也可以
jmppok 2014-07-01
  • 打赏
  • 举报
回复
Socket发送的都是数据流, 结构体必须序列化成字节流后才可以发送. C++ 和 Java通讯要注意编码问题. 协议简单的话,可以自己写. 复杂的话可以用pocobuffer之类的开源
赵4老师 2014-07-01
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
spaceman10 2014-07-01
  • 打赏
  • 举报
回复
引用 6 楼 swgshj 的回复:
底层通讯的send和recv函数应该都是面向字节流的。 把struct A { int id; string msg; }; 修改为 struct A { int id; char msg[MAX_LEN]; }; 假设 A是字节对齐的 //C++侧发送 A a; a.id=0x12; strcpy(a.msg, "hello"); //a.msg = "hello" 发送函数为send(sockid, &a, (sizeof(a,id) + strlen(a.msg))); 那么实际你发送出去的字节流为(十六进制): 12 00 00 00 68 65 6c 6c 6f 小端0x12 'h' 'e' 'l' 'l' 'o' //Java侧接收, 你使用java的接受函数,收到的也是字节流 12 00 00 00 68 65 6c 6c 6f
c++接受段要怎么弄啊?
spaceman10 2014-07-01
  • 打赏
  • 举报
回复
引用 2 楼 bdmh 的回复:
写到byte[]发送
引用 2 楼 bdmh 的回复:
写到byte[]发送
如何写啊,能给个例子吗?
梦想照旧实现 2014-07-01
  • 打赏
  • 举报
回复
底层通讯的send和recv函数应该都是面向字节流的。 把struct A { int id; string msg; }; 修改为 struct A { int id; char msg[MAX_LEN]; }; 假设 A是字节对齐的 //C++侧发送 A a; a.id=0x12; strcpy(a.msg, "hello"); //a.msg = "hello" 发送函数为send(sockid, &a, (sizeof(a,id) + strlen(a.msg))); 那么实际你发送出去的字节流为(十六进制): 12 00 00 00 68 65 6c 6c 6f 小端0x12 'h' 'e' 'l' 'l' 'o' //Java侧接收, 你使用java的接受函数,收到的也是字节流 12 00 00 00 68 65 6c 6c 6f
zilaishuichina 2014-07-01
  • 打赏
  • 举报
回复
数据包总共字节数len(4字节) + 本数据包代表的协议号(4字节)+ //根据协议号,得知这个包发的是struct A还是struct B id(4字节) + msg内容(X字节) //X = len - 4 - 4 - 4;既len = 4 + 4 + 4 + X
yangyunzhao 2014-07-01
  • 打赏
  • 举报
回复
现在做的游戏,其中有点点是C++与C#的网络通讯。我的做法是这样的: 1、C++定义一个结构体,是所有结构体的头,包含了版本号、数据长度、数据类型等定义。 2、所有可能通过网络传输的数据结构,都必须在头部包含上述结构体。 3、所有结构体,全部采用4字节对齐,如果不能对齐的,插入一些无意义的数据,强制对齐。 4、C#端收到后,先解析头,根据头的信息,再解析生成对应的结构体。
赵4老师 2014-07-01
  • 打赏
  • 举报
回复
string是对象,不是一段内存。不适合放在结构体中,也不适合放在IP包中。
bdmh 2014-07-01
  • 打赏
  • 举报
回复
写到byte[]发送
黑娃 2014-07-01
  • 打赏
  • 举报
回复
不建议发结构体,因为即便双方采用同样的语言和编译器,也可能因为填充字节的不同而导致结构体计算的大小不同。建议严格规定各个字段的大小和意义,依次发送。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧