谢谢, 请教一个问题

64 views
Skip to first unread message

nostalgia

unread,
Dec 14, 2009, 8:16:24 AM12/14/09
to spserver
lau stephen

谢谢你的这个spserver

想请教一下, 服务器端或者客户端向对方发送数据的时候,我是把数据放在了一个struct里面,服务端或客户端接收的时候, 怎么判断数据开始
或结束呢,
我现在是在数据的开头给了一个structinfo信息,structinfo是一个enum型的数据,

接收的时候对buffer进行强制类型转换,
//get struct info
byte stype = ((StructInfo*)spbuff->getBuffer())->type;
//user login info
if(stype == StructInfo::USERLOGININFO){
.....
}

数据结构是这样的

typedef struct tagUserLoginInfo {
StructInfo sinfo;
char mUserID[16];
char mPassword[16];
} UserLoginInfo, *PUserLoginInfo;

其实就是判断开始数据(只有一位), 如果和定义的类型相同,就知道是这段类型的数据, 不知道这样处理是否妥当, 谢谢


iunknown

unread,
Dec 15, 2009, 9:02:04 AM12/15/09
to spserver
你可以使用类似下面这样的一个 Decoder 来实现。

//
// +----+----+----+----+----+----+-...
// | length | structure
// +----+----+----+----+----+----+-...
//
class ChunkMsgDecoder : public SP_MsgDecoder {
public:
ChunkMsgDecoder() {
mBuffer = NULL;
mLen = 0;
}

virtual ~ChunkMsgDecoder() {
if( NULL != mBuffer ) free( mBuffer );
mBuffer = NULL;
}

virtual int decode( SP_Buffer * inBuffer ) {
int ret = eMoreData;

int len = 0;

if( inBuffer->getSize() > sizeof( len ) ) {
memcpy( &len, inBuffer->getBuffer(), sizeof
( len ) );

if( inBuffer->getSize() >= ( sizeof( len ) +
len ) ) {
ret = eOK;

if( NULL != mBuffer ) free( mBuffer );

mLen = len;

mBuffer = malloc( len + 1 );
((char*)mBuffer)[ len ] = '\0';

inBuffer->erase( sizeof( len ) );
inBuffer->take( (char*)mBuffer, len );
}
}

return ret;
}

int getLen() { return mLen; }

void * getBuffer() {
return mBuffer;
}

private:
int mLen;
void * mBuffer;
};

xuyean

unread,
Dec 21, 2009, 4:23:27 AM12/21/09
to spserver
dear stephen.nil:
 
为什么spbuffer的
 
int SP_Buffer :: take( char * buffer, int len )
{
len = sp_evbuffer_remove( mBuffer, buffer, len - 1);
buffer[ len ] = '\0';
return len;
}
 
中 len 要减去一呢, 这样我一次传 12个字节过来, 如果take 12个的话, 实际上只提出11个, 还残留1个字节(虽然被置为 \0)在buffer中
下次再传12个, 总共就变成13个字节了,数据就乱了。。。  迷惑。。请教。。。打搅。。。
 

lau stephen

unread,
Dec 21, 2009, 5:52:43 AM12/21/09
to spse...@googlegroups.com
这个是由于想确保 buffer 中的内容是有 '\0' 结束的。
不过这个接口的设计的确不太好,从接口上看不出具体的含义。

如果遇到问题,暂时先用 getBuffer 和 erase 两个接口组合来实现这个接口的功能吧。

2009/12/21 xuyean <xuy...@gmail.com>:

xuyean

unread,
Dec 24, 2009, 3:37:13 AM12/24/09
to spserver
 
不知道哪个是你的邮箱, 所以发了两次, 望见谅
 
lau stephen:
 
  你好, 请教一下
int StructMsgDecoder::decode(SP_Buffer * inBuffer ){
printf("in decode....%d\n", inBuffer->getSize());
int ret = eMoreData;
int len = 0;
if(inBuffer->getSize() >= MINIMUMSTRUCTPACKAGESIZE){
StructInfo si;
memcpy(&si, inBuffer->getBuffer(), MINIMUMSTRUCTPACKAGESIZE);
if (inBuffer->getSize() >= si.size)
{
ret = eOK;
if( NULL != mBuffer ) free( mBuffer );
mLen = si.size;
mBuffer = malloc( mLen + 1 );
((char*)mBuffer)[ len ] = '\0';
//inBuffer->take((char*) mBuffer, mLen + 1);
memcpy(mBuffer, inBuffer->getBuffer(), mLen);
inBuffer->erase(mLen);
}
}
return ret;
}
 
如果每次传过来的数据都是没有符合数据要求的,一直return eMoreData, 那这样inBuffer的size不是要一直涨下去。。。内存不是一只暴涨。。。 很迷惑,望指点迷津, 感激涕零。。。
 
2009-12-24

xuyean
 

lau stephen

unread,
Dec 24, 2009, 4:40:53 AM12/24/09
to spse...@googlegroups.com
的确就是这样的。这个内存的大小,要视乎这个请求包的大小。

如果请求包特别大,并且不希望内存一直增长,也可以实现,就是实现比较复杂。
可以使用 DefaultDecoder ,每次收到任何一段数据,都调用 handle 方法,在 handle 方法中,自行组包。

2009/12/24 xuyean <xuy...@gmail.com>:

> --
>
> You received this message because you are subscribed to the Google Groups
> "spserver" group.
> To post to this group, send email to spse...@googlegroups.com.
> To unsubscribe from this group, send email to
> spserver+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/spserver?hl=en.
>

Reply all
Reply to author
Forward
0 new messages