2013-08-29 94 views
3

我有一个问题给你。C++如何通过套接字发送对象?

我有这个类:

`

#define DIMBLOCK 128 
#ifndef _BLOCCO_ 
#define _BLOCCO_ 

class blocco 
{ 
    public: 
     int ID; 
     char* data; 


     blocco(int id); 
}; 

#endif 




blocco::blocco(int id) 
{ 
    ID = id; 
    data = new char[DIMBLOCK]; 
} 

`

和应用有一个客户端和服务器。 在我的服务器的主体中,我用这种方式实例化了这个类的一个对象: blocco a(1);

之后,我使用套接字打开客户端和服务器之间的连接。 现在的问题是:如何将这个对象从服务器发送到客户端或反之亦然? 你能帮我吗?

+0

可能需要套接字代码。即使如此,除非你建立了一个精心制作的RPC系统,否则你得到的最好的结果就是*副本*(这可能是你所需要的)。 – WhozCraig

回答

5

在字面意义上,不可能通过TCP连接发送对象。套接字只知道如何传输和接收字节流。所以你可以做的是通过TCP连接发送一系列字节,格式化的方式是接收程序知道如何解释它们并创建一个与发送程序想要发送的对象相同的对象。

该过程被称为序列化(和接收端的反序列化)。序列化不是内置于C++语言本身,所以你需要一些代码来完成它。它可以通过手工或使用XML,或通过Google协议缓冲区完成,也可以通过将对象转换为人类可读文本并发送文本或任何其他方式来完成。

查看更多信息here

+0

所以,不可能这样做:ret = send(sock,reinterpret_cast (&a),sizeof(blocco),0);? – rosekarma

+1

不可以。不会有多种原因,例如,它不会遵循指针(例如,以这种方式发送的blocco的接收器将接收(数据)指针的值而不是(数据)指向的字符,这不会有用)。它也不能正确处理填充和尾部问题。 –

+0

@rosekarma那会有什么好处呢?你将如何编写代码来接收数据,因为你几乎不知道你发送了什么字节。要编写代码来接收数据,首先需要知道的是ID有多少个字节进行编码。但是你甚至不知道 - 更糟糕的是,如果你改变编译器,平台等等,它会改变。 –

2

你可以使用serialization来做到这一点。这意味着将对象拉成碎片,以便您可以将这些元素发送到套接字上。然后你需要在连接的另一端重建你的班级。在Qt中有QDataStream class提供这样的功能。结合QByteArray,您可以创建一个可以发送的数据包。想法很简单:

发件人:

QByteArray buffer; 
QDataStream out(&buffer); 
out << someData << someMoreData; 

接收机:

QByteArray buffer; 
QDataStream in(&buffer); 
in >> someData >> someMoreData; 

现在你可能要提供额外的构造函数:

class blocco 
{ 
    public: 
     blocco(QDataStream& in){ 
      // construct from QDataStream 
     } 

     //or 
     blocco(int id, char* data){ 
      //from data 
     } 
     int ID; 
     char* data; 


     blocco(int id); 
}; 

extended example

-1

我不知道我会为此付出多少伤害,但是我尝试了这一点,尽管我应该分享它。我是套接字编程的初学者,所以不要生气。

我所做的是我创建了一个类的大小的数组(代表服务器端的内存块)。然后,我在客户端编辑了内存块,并将该块内存作为对象进行了类型转换!我设法从客户端发送一个对象到服务器。

示例代码:

blocco *data; 
char blockOfData[sizeof(*data)]; 

if(recv(serverSocket, blockOfData, sizeof(*data), 0) == -1) { 
    cerr << "Error while receiving!!" << endl; 
    return 1; 
} 

data = (blocco *)blockOfData; 

现在你可以做任何你想用这个作为一个指向对象这个数据。请记住,不要尝试删除/释放此指针,因为此内存已分配给堆栈上的数组blockOfData。

希望这有助于如果你想实现这样的事情。 PS:如果你认为我所做的是不好的编码方式,请让我知道为什么。我不知道为什么这是一个坏主意(如果这样做实际上是个坏主意)。谢谢!!

+0

如果您想知道为什么这种方法无效,请尝试在recv()返回后打印出'received'blocco对象的'data'成员项所指向的字符串。你会发现字符串没有被传输,你会打印出垃圾或者(更可能)你的程序在试图解引用数据的指针时崩溃,它被设置为指向一个有效的地址发送者的内存空间,但不在接收者的内存空间中。 –

+0

我在我的macbook上实现了这一点,并在同一台机器上同时运行客户端和服务器。我成功地访问了数据,并没有面临任何崩溃/垃圾值问题。也许如果我尝试在具有不同endian系统的多个系统上执行此操作,我会遇到问题吗? –

+0

我现在明白你的观点,如果我有指点,我会面对这些问题。虽然如果我有一个字符串(我在我的代码中),那么我不会面对这些问题。 –