ServerSocket和ClientSocket发自定义消息的问题

itbear 2008-06-28 06:40:15

如果将自定义消息的包头定位成一个结构体(有一个成员用于指示包体长度),包体视不同情况定义为不同的结构体,那么ServerSocket和ClientSocket之间应该如何发送和接收呢?
例如:
【包头】
typedef struct Msg_header
{
int command;//命令字
int bodyLength;//包体长度
}Header;

【若干不同的包体】
typedef struct Msg_body1
{
//视不同情况定义不同的结构
...
...
}Body1;

typedef struct Msg_body2
{
//视不同情况定义不同的结构
...
...
}Body2;

……
typedef struct Msg_bodyN
{
//视不同情况定义不同的结构
...
...
}BodyN;
...全文
232 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
pp616 2008-06-30
  • 打赏
  • 举报
回复
阻塞顺着收就可以 没什么说的.

非阻塞的试试这样.


UINT RecvSize = 0;
TMemoryStream * stm = new TMemoryStream;
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket)
{
char *buf = (char *)malloc(Socket->ReceiveLength());
Socket->ReceiveBuf(buf, Socket->ReceiveLength());
RecvSize += Socket->ReceiveLength();
stm->Write(buf, Socket->ReceiveLength());
free(buf);

while(RecvSize > sizeof(Msg_header))
{
Header * pHead = (Header *)stm->Memory;
if(RecvSize >= pHead->bodyLength+sizeof(Msg_header) )
{
//处理数据
/*
例如 Body1 *pBody1 = (Body1 *)(pHead++);
code...
*/

RecvSize = 0;
if(RecvSize > pHead->bodyLength+sizeof(Msg_header) )
{
stm->Seek(0, 0);
stm->Write((char *)stm->Memory + pHead->bodyLength + sizeof(Msg_header),
stm->Size - pHead->bodyLength - sizeof(Msg_header));
stm->SetSize(stm->Size - pHead->bodyLength - sizeof(Msg_header));
RecvSize = stm->Size;
}
else
{
stm->Clear();
}
}
else
{
break;
}
}
}
僵哥 2008-06-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 jxw1987628 的回复:]
我觉得可以再在你的head里面加个字段

int body_type;来表示你的body用的是哪种类型的body。

然后再组成一个完整的包。
[/Quote]
在发送的时候,这样子是可以的,但是在接收的时候,如果不想接收粘连部分,还是得分两次。
jxw1987628 2008-06-29
  • 打赏
  • 举报
回复
我觉得可以再在你的head里面加个字段

int body_type;来表示你的body用的是哪种类型的body。

然后再组成一个完整的包。
僵哥 2008-06-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 itbear 的回复:]
如果分开两次收发包头和包体,是不是这样:
【发送】
socket->send(...);//发送包头结构体
socket->send(...);//发送包体结构体
【接收】
socket->receive(...);//接收包头结构体
socket->receive(...);//接收包体结构体
[/Quote]
这样子可行

[Quote=引用 7 楼 itbear 的回复:]
引用 4 楼 itbear 的回复:
采用阻塞方式或非阻塞方式,在发送和接收包头、包体的时候有什么不同么?
可否给出一些示例代码?


如果是非阻塞,不是每当有数据发过来的时候就触发一次onReceive()事件么?这样的话包头、包体相当于是在两个不同的事件里接收到的,如何将这两个包关联起来呢?
[/Quote]
你可以把它暂存起来,他们都有一个名为Data的指针(void*),你可以创建一个结构存储于其中表示你当前socket的数据
itbear 2008-06-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 itbear 的回复:]
采用阻塞方式或非阻塞方式,在发送和接收包头、包体的时候有什么不同么?
可否给出一些示例代码?
[/Quote]

如果是非阻塞,不是每当有数据发过来的时候就触发一次onReceive()事件么?这样的话包头、包体相当于是在两个不同的事件里接收到的,如何将这两个包关联起来呢?
itbear 2008-06-29
  • 打赏
  • 举报
回复
如果分开两次收发包头和包体,是不是这样:
【发送】
socket->send(...);//发送包头结构体
socket->send(...);//发送包体结构体
【接收】
socket->receive(...);//接收包头结构体
socket->receive(...);//接收包体结构体

僵哥 2008-06-29
  • 打赏
  • 举报
回复
没有不同。不能给出示例代码。
itbear 2008-06-29
  • 打赏
  • 举报
回复
采用阻塞方式或非阻塞方式,在发送和接收包头、包体的时候有什么不同么?
可否给出一些示例代码?
僵哥 2008-06-28
  • 打赏
  • 举报
回复
先接收Msg_header,然后再根据Command具体接收。

1,316

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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