软件设计中常用技术
在软件设计中我们为了解决某些问题常用些技术
让问题可以得到更快更好的解决
下面写出一些经常使用的技术,也欢迎大家补充
对每一个技术,会说明使用到的编程方面技术,功能,实现,优缺点,使用场合,这样以后开发时会更容易
现在讲述的内容
依次是
回调函数
通信包传送技术,主要是定长包与变长包构成
长连接与短连接,由c/c++版整理而来
plugin技术,plugin使用的是函数指针形式,在"软件设计中常用模式"内有说明
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
有个问题,一直没想好答案,比如有些函数,嵌套有5,6层深,当最低一层出错返回时应该怎么做?一层一层判断返回想得头都大了,用setjmp/longjmp好像一不太好,应为有好多地方用到这样的函数,现在我的方法是直接exit退出了,呵呵,好像也没太多问题,但如果精灵进程怎么办?想知道你们都是怎么做的?
函数指针是很灵活吧
需要用的时候就用
这样很方便
哈哈,thanks无双,你总结的好详细啊,俺最喜欢用函数指针了。
优缺点:
定长包长度固定, 因此接收时只要接收指定长度的包就可以, 不用先读包长度再读包内容 , 节省了socket 操作次数, 提高了程序运行速度
如果在传送的数据长度可变,那么按 最大长度算,如果最大与最小包长度差别很大, 并且最大包发送频率不是很高,那么会浪费很多带宽, 缺点主要是带宽
另外如果以后增加新类型数据包的话 , 如果长度大于现在定义的长度, 那么双方接口要重定义, 接口扩展性不是很好也是一个缺点
变长包可以发送任意长度的包, 并且每次只增加包长度的带宽开销, 所以不会给带宽带来很大影响
另外可以传送任意长度的包, 这使以以后增加包类型时会显得很灵活
但是每次发送前都要先发送长度, 再发送内容, 接收也是一样, 所以socket操作加多, 影响程序性能
使用场合:
定长包用于包长度差别不大或是相等的情况, 并且包的最大可能长度是已知的,以后就是再增加包类型长度也不会超过这个数
变长包用于包长度相关很大和包最大长度不可知情况, 就是说以后增加的包长度可能还会更大
第二种,通信包传送技术
介绍
在使用TCP socket等在两个进程间传送数据时,我们会遇到双方如何得知一个包到什么地方结束. 因为TCP socket并不是发一个包,对方就会收到同样大小的包的, TCPsocket是一种流, 它只保证流内内容的有序, 不保证流长度的一致.可能一发多收或是一次收到多次发的包。另外TCP在数据被接收后会从接收缓冲中删除, 所以如果不想自己管理缓冲区的话, 还是每次只接收正确的长度好
在通信中常用的有两种包格式,一种是定长包, 另一种是变长包
定长包就是每次发送时包长度都是固定的,接收方只要接收这么长的包就可以了。
变长包就是每次发送的包长度都是可变的, 由于TCP是形格式,接收方必须知道此次接收要接收多长的包
它们的区别只是在于每次发的包长度是可变还是定长, 没有定义定长包包内数据必须是定长, 有时也使用定长包传送可变长内容, 但是如果包长度不够的话那么要填充一些值, 并有可以得到包长度信息的标志 ,包最大长度不会超过双方规定长度
技术:socket的发送与接收,变长包格式
socket的发送与接收,这是基本的socket编程,这里不再多说
变长包格式:
一般通信使用的变长包格式是
2个字节的short 包内容
前面两个字节保存包全部长度,接收方接收时先接收两个字节, 得知包大小, 然后再根据包大小从socket中读出包内容
使用两个字节的原因是unsigned short已可以表示65535, 这在多数情况下都已够用, 当然你也可以自己定义这个, 没有标准说一定要是一个unsigned short类型
定长包格式随着注意就是有时包长度不够的话, 要双方协议好
包的收发:
定长包收发: 每次发送指定长度的包 , 如果包长度不够那么填充
变长包收发 发送时先发送包长度, 再发送包内容 ,接收时先接收包长度,再根据包长度接收包内容
优点: 灵活, 可以方便的扩充或是给用户提供自己实现策略
缺点: 对第二种, 用户的不良代码会影响整个系统稳定性
对第一种, 如果接口参数相差比较大的话,那么会传入过多无用参数, 影响对程序理解
适用于想让用户提供定制方法或是接口参数相近,想方便扩展功能而不必修改过多代码的场合
谢谢楼上鼓励,现在继续
回调函数的使用场合
1。有一组功能相近的函数,它们接口参数相差不大并且想方便的扩展接口,提高程序灵活性,这种典型的是内核中文件操作接口(如read)对外提供一个统一的READ接口,内核实现时根据不同的文件类型调用不同驱动的read函数
2 想封装类或库的具体实现,但是还想让用户可以自己定制一部分操作,提高程序的灵活性 , 这种可以看unix下的信号处理或是线程函数, 信号处理定义了一个统一接口,接口具体实现由用户决定, 当存在特定事件时由系统调用用户回调
可见回调是在当某些接口或是操作没有确定下来时解决问题的一种好方法, 它提供灵活的机制让用户可以方便的增加、修改某些接口而不必对代码做太大修改
第一种也可以使用switch实现,但是使用回调让代码看起来更简洁, 并且新功能添加更容易 如果一组操作参数差别比较大的话, 使用那么switch会更方便, 因为不必为每个函数都定义多余的参数
好!继续
1 回调函数技术
回调函数的实现就是函数指针,定义一组函数,它们有相同的参数类型与返回值,然后通过函数指针的方法对他们进行操作,这就构成了回调函数。常见的有linux内核驱动中的read write等系统调用,它们的实现都不一样,但是接口都一样,上层调用时内核会自动根据设备类型通过函数指针的形式调用他们。
使用到的编程技术:
函数指针的定义方法
int func(int a,int b,int c);
int (*fp)(int ,int ,int) ;//定义一个函数指针,
fp=func;//这个函数指针可以指向有相同参数与返回值的函数,注意两个相同