你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

搜狗workflow——C++并行计算与异步网络引擎 序列化与反序列化 代码分析(十三)

2021/12/26 16:06:14

2021SC@SDUSC

目录

一.关于序列化和反序列化

1.含义

二.序列化和反序列化的关键代码展示

1.message.h

2.message.cc

3.server.cc

4.client.cc

docs/tutorial-10-user_defined_protocol.md · 搜狗开源/workflow - Gitee.com


本篇是代码分析的最后一篇,在这里做一个关于序列化与反序列化的总结。

一.关于序列化和反序列化

1.含义

  对象的序列化(Serialization),即把一个对象以流的方式,写入到文件中保存,叫写对象,也叫对象序列化,对象中包含的不仅仅是字符,使用字节流。

       对象的反序列化(deserailization),即把文件中保存的对象,以流的方式读取出来,叫做读取对象,也叫对象的反序列。读取的文件保存的都是字节,使用字节流。

对象序列化的作用:在传递,和保存对象(object)的时候,保证对象的完整性和可传递性。
 

首先我们定义了一个序列化和反序列化的接口,在ProtocolMessage.h里;在接口中定义了两个函数,分别是encode函数:序列化函数,append函数:反序列化函数。

部分代码示例如下:

class ProtocolMessage : public CommMessageOut, public, CommMessageIn
{
private:
    virtual int encode(struct iovec vectors[], int max) = 0;//encode函数为序列化函数
    virtual int append(const char *buf, size_t size) = 0;//append函数为反序列化函数

……

2.优点

①将对象转为字节流存储到硬盘上,当JVM停机的话,字节流还会在硬盘上默默等待,等待下一次JVM的启动,把序列化的对象,通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)。

 ②序列化成字节流形式的对象可以进行网络传输(二进制形式),方便了网络传输。

 ③通过序列化可以在进程间传递对象。

二.序列化和反序列化的关键代码展示

1.message.h

在message.h中,定义了具体的方法。

class TutorialMessage : public ProtocolMessage

{

private:

virtual int encode(struct iovec vectors[], int max);

virtual int append(const void *buf, size_t size);

public:

int set_message_body(const void *body, size_t size);

void get_message_body_nocopy(void **body, size_t *size)

{

*body = this->body;

*size = this->body_size;

}

2.message.cc

在message.cc中实现了encode,append方法。

 

int TutorialMessage::encode(struct iovec vectors[], int max/*max==8192*/)

{

uint32_t n = htonl(this->body_size);

memcpy(this->head, &n, 4);

vectors[0].iov_base = this->head;

vectors[0].iov_len = 4;

vectors[1].iov_base = this->body;

vectors[1].iov_len = this->body_size;

return 2; /* return the number of vectors used, no more then max. */

}

int TutorialMessage::append(const void *buf, size_t size)

{

if (this->head_received < 4)

{

size_t head_left;

void *p;

p = &this->head[head_received];

head_left = 4 - this->head_received;

if (size < 4 - this->head_received)

{

memcpy(p, buf, size);

this->head_received += size;

return 0;

}

3.server.cc

在server.cc中实现了交互的过程方法。

void process(WFTutorialTask *task)

{

TutorialRequest *req = task->get_req();

TutorialResponse *resp = task->get_resp();

void *body;

size_t size;

size_t i;

req->get_message_body_nocopy(&body, &size);

for (i = 0; i < size; i++)

((char *)body)[i] = toupper(((char *)body)[i]);

resp->set_message_body(body, size);

}

4.client.cc

在client.cc方法中用锁实现与客户端交互:

 

WFTutorialTask *task = MyFactory::create_tutorial_task(host, port, 0, callback);

task->get_resp()->set_size_limit(4 * 1024);

Workflow::start_series_work(task, [&mutex, &cond, &finished](const SeriesWork *)

{

mutex.lock();

finished = true;

cond.notify_one();

mutex.unlock();

}

----------------------------------------------------------------------------------------------------------------------

代码来源:

docs/tutorial-10-user_defined_protocol.md · 搜狗开源/workflow - Gitee.com