处理回包的方法讨论,是不是一定要用switch?

lsaturn 2005-06-15 02:59:18
在网络编程中,对于回包的处理总是需要一个循环的,不断的接包,然后根据包的内容进行处理.
这个循环就好象windows的消息循环,mfc处理这种循环其实还是使用switch的方法,不过包装了一些宏来处理,看起来好象不是switch.不过要添加一个消息处理就必须添加一个宏,比如ON_XXMESSAGE,就面向对象的设计来看,这是违反了面向对象的原则的,违反了Open-Close原则的.相信大家在编程的时候,可能遇到过添加一个消息处理函数,结果发现没有作用,后来发现原来是忘了写一个对应的宏.这个设计其实隐藏着错误.
网络编程里面回包其实也是这样一个处理,我尝试过使用模板,重载等等手段都无法摈弃switch(究其原因还是因为运行期完全没有类型这个概念,由包到类型的鸿沟无法逾越----我本来想通过命令字来生成类型信息然后激发重载机制的).
我想跟诸位讨论一下,你们是怎么处理回包的消息循环的?希望大家不要说我不实用,毕竟是讨论,我也想追求一种美感.
...全文
296 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
lsaturn 2005-06-28
  • 打赏
  • 举报
回复
另外这次的优化使我明白了为什么现在的语言需要Reflect,为什么现在的语言需要垃圾回收,这些是出于什么需要而出现的语言要素.
lsaturn 2005-06-28
  • 打赏
  • 举报
回复
程序设计的流派很多,我们就不要互相争吵了,我觉得这是个哲学问题,最近看得几本书几个大师还打得不可开交呐,我只是想跟大家讨论一下.因为最近学了template和重构,所以想要练练手
DreamForever 2005-06-24
  • 打赏
  • 举报
回复
毫无道理,把时间浪费在这上面。

一、没觉得switch\case结构不优美
二、过度的面向对象思想不是c++程序员的宗旨,我在程序中还经常使用goto语句呢,一般是goto QUIT这样的形式,简洁明快
三、效率不能在最后才考虑,尤其是服务器程序,应该是效率为主,可以看看apache的源码来理解这点
「已注销」 2005-06-23
  • 打赏
  • 举报
回复

一般设计时候不考虑效率,到出了效率瓶颈的时候再考虑

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

汗.................
aben456 2005-06-23
  • 打赏
  • 举报
回复
switch该用的还是要用的,个人意见
lsaturn 2005-06-23
  • 打赏
  • 举报
回复
我觉得过早的优化不是什么好事
lsaturn 2005-06-22
  • 打赏
  • 举报
回复
看来楼上的兄弟是实用主义啊.
不过我觉得对这个的讨论对于程序的结构和测试有很大的帮助.
elssann 2005-06-21
  • 打赏
  • 举报
回复
孔乙几在讨论茴香豆的几种写法。
lsaturn 2005-06-21
  • 打赏
  • 举报
回复
一般设计时候不考虑效率,到出了效率瓶颈的时候再考虑
sunhuiNO1 2005-06-21
  • 打赏
  • 举报
回复
大家想法不错,但是考虑效率没?
lsaturn 2005-06-21
  • 打赏
  • 举报
回复
C#好象可以根据名字生成类
ringphone 2005-06-21
  • 打赏
  • 举报
回复
add_packet_handler(KEEP_ALIVE, process_keep_alive);
不用switch,if/else,就只能是这种方法,原理就是遍历数组。
如果有一种办法,可以根据类名字符串动态生成类,那就解决了,就是能实现下面一个函数
Packet* NewClass(char* classname)
比如classname=“SLoginPacket”这个函数能够return new SLoginPacket,这里同样不能用if/else,查表之类,而是完全根据传入参数生成类,能够把参数两边的"去掉,new classname
不知是否可能实现。
lsaturn 2005-06-17
  • 打赏
  • 举报
回复
顶一下,希望大家更多的参与讨论,奉献自己的方法.
以上说的方法还都是比较常规的方法.
lsaturn 2005-06-16
  • 打赏
  • 举报
回复
add_packet_handler(KEEP_ALIVE, process_keep_alive);
就是这个表很可恶,就是没有办法去掉啊.
yoqi 2005-06-16
  • 打赏
  • 举报
回复
另一个可行的处理方式是这样,简单手工写一下,代码没验证:


struct packet_t
{
int len;
int cmd;
char data[1];
};

typedef void (*pfn_process_packet)(packet_t*);

struct packet_handler_t
{
int cmd;
pfn_process_packet pfn;
};

vector<packet_handler_t> g_packet_handler_map;

void add_packet_handler(int cmd, pfn_process_packet pfn)
{
packet_handler_t ph;
ph.cmd = cmd;
ph.pfn = pfn;
g_packet_handler_map.push_back(ph);
}

add_packet_handler(KEEP_ALIVE, process_keep_alive);
add_packet_handler(PEER_LOGIN, process_peer_login);
add_packet_handler(PEER_LOGOUT, process_peer_logout);
...

void process_packet(packet_t* packet)
{
for (int i = 0; i < g_packet_handle_map.size(); ++i)
{
if (g_packet_handler_map[i].cmd == packet->cmd)
{
if (g_packet_handler_map[i].pfn)
g_packet_handler_map[i].pfn(packet);

break;
}
}
}
ringphone 2005-06-16
  • 打赏
  • 举报
回复
可以使用插件,服务程序启动时扫描插件目录,加载所有插件,也可以动态监视随时加载,新增命令服务程序向所有插件的查询接口询问是否支持,支持则调用其处理接口。
AntonlioX 2005-06-16
  • 打赏
  • 举报
回复
up
Zhymax 2005-06-15
  • 打赏
  • 举报
回复
vc作为开发工具提供了很大的灵活性,可以手工也可以用ClassWizard来添加消息函数,如果用ClassWizard就可以尽量避免搂主所说的问题,如果要手工添加消息函数,我局的完全可以再WinPorc中处理,不用去理会vc中的宏
jiudon 2005-06-15
  • 打赏
  • 举报
回复
同意晨星的说法,呵呵,!!
晨星 2005-06-15
  • 打赏
  • 举报
回复
对了,楼主所说的“就面向对象的设计来看,这是违反了面向对象的原则的,违反了Open-Close原则的”具体是指什么呢?不是很懂,希望楼主能解释一下。
加载更多回复(13)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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