如何制定网络通讯协议(欢迎大家来讨论)

mynamelj 2005-09-12 10:44:03
如何去制定网络通讯协议?
比喻说像即时通、五子棋.它们都有自已的通信规则,也就是说如何跟据这些规则来编写网络程序?

诚心请向各位请教(越详细越好)谢谢.
...全文
780 点赞 收藏 37
写回复
37 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
skykeen 2005-10-15
xml的扩充性很好,它的开放性结构体系容易和其它模块(包括第三方的)交互
回复
月吻长河 2005-10-15
用XML比较好
也可以参考http,设计成文本形式的
回复
lianglp 2005-09-28
用XML当协议用的多吗?
回复
luxingjyp 2005-09-28
8错,有收获啊
回复
2021‘someday 2005-09-25
就是相当于信息包了,分为包头和包体最好啊,
回复
alen_ghl 2005-09-25
我不是说过,可以不用结构体,看你程序的应用,如果你需要引用里面的成员,用结构体方便
不用自己去逐个解析出来

to: mynamelj(风之羽翼) ( )
公司不让上qq,所以我qq基本上不用,你可以给我发邮件
回复
gomoney 2005-09-25
程序两端都知道发的数据包的结构,可以准确读出需要的信息就可以了嘛,当然规范性和可扩充性多考虑一些更好.
回复
周江涛 2005-09-23
没必要用结构体吧?我做的一个项目,就是用字符串组合起来的,

比如注册用户 格式 = 交易码+用户名+密码+电子邮件
"001|张三|pass|zhang@163.com"
返回格式 = 交易码+用户ID
"001|13"


验证
"002|张三|pass|"
返回格式 = 交易码 + 用户ID
"002|13"
失败返回"002|0"
接收端知道此格式就可以了,写个截取子串的函数,可以取出任意想要的信息,也不用受结构体中定义的长度限制。
回复
alen_ghl 2005-09-21
整体架构
packet = head + data
head = PacketLength(包长,int) + RequestID(请求操作标识,int) + SequenceID(流水号,int)
我都定义为整型,足够用,而且换算也方便

RequestID 自己定义,比如
//--------------------------- Server Receive --------------------------------------------
//--------------------------- Client Send To Server--------------------------------------
#define SEND_MSG_TO_FRIEND 1 //CMsg1 index,friendId,myId,msg,time
#define FRIEND_IDENTITY_VALIDATE 2 //CMsg1
#define ADD_AS_FRIEND 3 //CMsg1
#define FRIEND_DETAIL 4 //CMsg1
#define FIND_FRIEND_BY_ID 5 //CMsg1
#define DELETE_A_FRIEND 6 //CMsg1
#define DELETE_SELF_IN_FRIEND 7 //CMsg1 选择在某人的好友中删除自己
#define ACCEPT_AS_FRIEND 8 //CMsg1 响应加为好友请求反馈信息(属于系统消息)
#define REFUSE_AS_FRIEND 9 //CMsg1 响应加为好友请求反馈信息(属于系统消息)

#define ONLINE 10 //CData index,myid
#define ONHIDE 11 //CData index,myid
#define OFFLINE 12 //CData index,myid

#define MULTI_SEND_MSG 13 //CMsg2 index,myid,friendidarray,msg,time

#define APPLY_SHOW_ONLINE 14 //CMsg3 index,myid,value 请求查看在线的人

#define TEST_BROADCAST_PWD 15 //CMsg4 index,id,broadcastpwd,msg
#define SEND_BROADCAST 16 //CMsg4
#define FIND_FRIEND_BY_NAME 17 //CMsg4 index,myid,name(msg)

#define CHANGE_PERSONAL_INFO 18 //CMsgModifyPI index,myid,mask,name,address,phone,fax,email,homepage,photoid,canbeadd,department,sex,age,description

#define CHANGE_PASSWORD 19 //CMsgModifyPwd index,myid,oldpwd,newpwd
#define HAVE_ID_LOGIN 20 //CMsgModifyPwd index,id,pwd(oldpwd)

#define APPLY_ID_LOGIN 21 //CMsgPerson index,name,address,phone,fax,email,homepage,photoid,canbeadd,department,sex,age,pwd,description

//-------------------------------- Server Send To Client --------------------------------
//-------------------------------- Client Recv From Server ------------------------------
#define RE_ADD_AS_FRIEND 31 //CMsg3 index,myid,value(0,1,2,3)(别人拒绝,成功加入,要求验证人份,此人已经为好友)
#define RE_TEST_BROADCAST_PWD 32 //CMsg3 index,myid,value (0,1) 密码错误,密码正确
#define TOTAL_ONLINE 33 //CMsg3 index,myId,Value 响应发送的总在线人数信息
#define RE_LOGIN_INFO 34 //CMsg3 index,myid,value (0,1,2) 帐号不存在,密码错误,OK

#define RECV_SHOW_ONLINE 35 //CShowOnlinePeople
#define FOUND_FRIEND_BY_NAME 36 //CShowOnlinePeople

#define APPLY_ID_OK 37 //CData index,myid(收到这个信息,这表示登陆成功)
#define ID_NOT_FOUND_BY_ID 38 //CData
#define NAME_NOT_FOUND_BY_NAME 39 //CData
#define REQUIRE_IDENTITY_VALIDATE 40 //CData
#define ONHIDE_OK 41
#define ONLINE_OK 52

#define FOUND_FRIEND_BY_ID 43 //CMsgPerson
#define RE_FRIEND_DETAIL 44 //CMsgPerson

#define ALL_FRIEND_ID 45 //CMsg2 index,id,friendidarray(收到这个信息,这表示登陆成功)

#define ONLINE_FRIEND 46 //CMsgOnlineFriend index,id,aFriendid,aFriendstate,aFriendIP,aFriendPort

#define BE_ADDED_AS_FRIEND 47 //CMsg1 响应好友加入的消息
#define SYSTEM_BROADCAST 48 //CMsg1


SequenceID:如果客户端连着多次发送同一种消息(比如修改密码),服务器端处理完后,把SequenceID号一起返回,用户就知道此次处理的结果是对应于哪次的操作了

你可以为每个消息定义相应的结构体,也可以直接分析。建议定义结构体
由于有包长,所以只需要定义一个足够大的buf来存数据,但发送的时候只发送PacketLength长度的数据就可以了,PacketLength的长度自己在程序中计算,
接收方也一样,先取出包头(其长度固定,这里是12字节),通过PacketLength的值来指定还需要接收多长的数据(PacketLength-12),在通过RequestID判断是何种操作,用相应的结构体来接收存贮
在进行相应的操作

不知道说清楚没?如果还不清楚,我这里有份资料,你可以找我要alen_ghl@hotmail.com

回复
danscort2000 2005-09-21
看楼上几位的包头定义思路不错,实际操作有问题,
不要使用BOOL bool long int WORD DWORD这类在不同编译条件可能产生分歧的类型
应该使用
char / BYTE
_int32
_int64
等明显指定数据长度的类型,
特别注意不要使用BOOL/bool
否则你的包在跨越到64位环境的时候将很有可能崩溃掉
回复
mynamelj 2005-09-21
大家各抒己见吧.
回复
mynamelj 2005-09-21
TO:alen_ghl(东方求*) ( ) 信誉:100

接收方也一样,先取出包头(其长度固定,这里是12字节),通过PacketLength的值来指定还需要接收多长的数据(PacketLength-12),在通过RequestID判断是何种操作,用相应的结构体来接收存贮
在进行相应的操作
-----------------------------------------------------------------------------------------


你的想法有点和我一样,收到相应的消息,用相应的结构去接收数据.由于我没有实际做这方面程序,所以
一直没有方向感,谢谢你的回答.

能加我的QQ吗?常在线.
QQ:154828
回复
sdcer 2005-09-20
回复人: mynamelj(风之羽翼) ( ) 信誉:105 2005-9-16 18:45:45 得分: 0



TO: sdcer(独钓雪) ( ) 信誉:62

那有什么办法可以解决这个问题呢?





我前面已经讲了,就是定义数据包头和数据实体。



如下所述:
不要使用结构体,因为结构体必须定义足够的字符串的长度,这个长度当然是要适应最坏的情况,比如文件名为MAX_PATH的长度,但事实上,在很多情况下,我们实际传输的文件名长度并不需要这么多,这就加剧了网络传输的负担,降低了效率。

最好的通讯方式应该是:
定义数据包头 + 数据体

数据包头中包括:版本、数据包的长度(包头+包体,或只有包体,视你的兴趣和具体问题而定),包体标号(顺序号)等

包体中的数据包括:实际的数据。

其中包头信息的每个字段应该规定一定的长度。
回复
hzyyxx 2005-09-20
可以参照radius协议
回复
mynamelj 2005-09-20
老大~我不是要EMAIL协议啊.
回复
xhzxlqt 2005-09-20
参考SMTP
回复
mynamelj 2005-09-20
up
回复
hjunxu 2005-09-16
可以用soap.
回复
mynamelj 2005-09-16
up
回复
mynamelj 2005-09-16
TO: sdcer(独钓雪) ( ) 信誉:62

那有什么办法可以解决这个问题呢?
回复
相关推荐
发帖
网络编程
创建于2007-09-28

1.8w+

社区成员

VC/MFC 网络编程
申请成为版主
帖子事件
创建了帖子
2005-09-12 10:44
社区公告
暂无公告