一封给“X教授”的回信(讨论Socket通信)
转载:http://www.cnblogs.com/tianzhiliang/archive/2011/03/02/1969187.html
前几天“X教授”发Email与我讨论Socket通信方面的问题,主要涉及4个方面内容,现将回信公布出来,希望园友们能积极参与讨论,提出更好的解决方案。
下面是“X教授”的来信:
===========================================================
您好,我看了您写的几篇博文,想请教你几个.net Socket通信方面的问题,这些问题以前一直困扰着我。
1、按照你深入探析C# Socket的文中的说法。
对于Socket的同步操作来说,Socket的RceiveBuffer和SendBuffer没有用处,因我发送时是从应用程序缓存(这里指字节数据)直接拷贝到基础系统发送缓冲区,接收时是从基础系统接收缓冲区拷贝到应用程序的缓存。
Socket本身的接收缓存与发送缓存,是否只与异步Socket操作有关。在异步操作中又分为两种,一种是以BeginXXX系列操作,以BeginSend为例,对这种操作我的理解是,从线程池中取一个线程,把数据拷贝到Socket的自带的SendBuffer中,调用BenginSend的主线程然后立刻返回,该发送线程挂起,由操作系统把SendBuffer中的数据拷贝到基础系统缓冲区,发送完成后,挂起的线程激活,调用EndSend进行相应的操作,释放异步对象等资源。
以上我的理解是否正确。
2、除XXXAsync系列操作外, BeginXXX系统的Socket操作是否也是用的完成端口机制。
3、.net与C/C++写的结构体通信。目前我熟悉的就两种:
第一种是了MarShal类进行结构体的转换操作,但托管与非拖管之间交互时的封送开销,使得其效率不高。
第二种是用流的方式去解析数据包。然后按包结构,一个字段一个字段的去读取。比如比流出读取一个浮点型,binr.ReadSingle();此种效率还可以。接收与解析好几M的数据没有问题。
我想问一下,有没有效率更高的方法。
4、服务器给客户端转发数据,当客户端接收包的地方堵塞(可能是socket.Receive),有没有什么好的方案,让服务器自动丢包。
===========================================================
下面是我的回信:
===========================================================
X教授,您好:
非常抱歉,最近比较忙,耽误给您回复了。对于您提出的几个问题,我只能作浅层次的回答,更深的研究,我们以后慢慢探讨,共同学习。
第一个问题:
你的理解是正确的,对于同步发送,是直接拷贝发送数据到基础系统的发送缓冲区,与Socket本身的Buffer无关。对于异步发送,是将Socket自带的Buffer空间内的所有数据,拷贝到基础系统发送缓冲区,并立即返回。
在实际开发中,个人觉得采用异步接受、同步发送。也许你会感到很惊讶,很明显,异步操作明显比同步操作效率高很多,为什么发送要采用同步呢?不知道你在开发过程中有没有遇到过“现在已经正在使用此 SocketAsyncEventArgs 实例进行异步套接字操作”错误,这个错误是由于SAEA对象在一个时刻中只能处于StartAccept、StartReceive、StartSend状态中的一种,试想,当Socket服务器处于高压力情形下,一条Socket连接在很短的时间内要发送大量数据,当Socket处于StartSend状态下尚未触发回调函数时,又一次调用此Socket的StartSend方法,便会抛出该异常。这也有改进方案:记录Socket的当前状态,并存储在Socket的UserToken对象下,当要执行StartSend时,判断状态。不过这样效率会很慢,远远低于同步发送的效率,当高并发时,还要用大量的锁机制来维护线程的同步,得不偿失。不知道你有没有更好的改进方案,如果有,请告知我,不胜感激。
第二个问题:
BeginXXX系统的Socket操作采用的是完成端口机制,在初始化SAEA对象时,会为SAEA对象设定回调函数。
SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs();
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
第三个问题:
建议使用流的方式解析数据包。
在解析数据包的过程中,不知道您有没有遇到过粘包的现象,我觉得对粘包的处理是影响解析效率的关键,请参见博文:http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813659.html。
第四个问题:
我觉得采用“心跳”是一个不错的解决方案。
“心跳”分为两种,第一种是客户端发起的心跳,第二种是服务端发起的心跳。
客户端发起的心跳:客户端每隔一段时间发送策略消息给Socket服务器,Socket服务器原路返回策略消息,如果客户端在设定时间段内没有收到Socket服务器的返回消息,经重试机制后,判定Socket服务器已Down,关闭连接。
服务端发起的心跳:服务端实时记录每条Socket的IO操作时间,每隔一段时间获取所有Socket列表的快照,扫描每条Socket,如果该Socket的IO操作时间距当前时间已超出设定值,则判定客户端Down,关闭连接。
一封给“X教授”的回信(讨论Socket通信)的更多相关文章
- C#调用C/C++动态库 封送结构体,结构体数组
因为实验室图像处理的算法都是在OpenCV下写的,还有就是导航的算法也是用C++写的,然后界面部分要求在C#下写,所以不管是Socket通信,还是调用OpenCV的DLL模块,都设计到了C#和C++数 ...
- “IT学子成长指导”专栏及文章目录 —贺利坚
迂者专栏关键词 就 业 大一 大二 大三 大四 自学 职 场 专业+兴趣 研究生 硕士 规 划 考 研 大学生活 迷 茫 计算机+专业 基本功 学习方法 编程 基 础 实践 读书 前 途 成 长 社团 ...
- 强哥的分享--如何使用Spring Boot做一个邮件系统
http://springboot.fun/ actuator是单机.集群环境下要使用Spring Boot Admin将各个单机的actuator集成越来 mvn clean package -Dm ...
- (转)我看PhD by 王珢
我看PhD by 王垠 前段时间看了一下这些关于 PhD 的负面信息: 一个专门反对读 PhD 的 BLOG 叫“100 Reasons NOT to Go to Graduate School”(下 ...
- [转]为什么我要用 Node.js? 案例逐一介绍
原文地址:http://blog.jobbole.com/53736/ 介绍 JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样, ...
- iOS:iOS开发非常全的三方库、插件等等
iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...
- 【转】为什么我要用 Node.js? 案例逐一介绍
原文转自:http://blog.jobbole.com/53736/ 介绍 JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样, ...
- Node.js(转) -- 临时来说还看不懂!
转自:http://blog.jobbole.com/53736/ 本文由 伯乐在线 - Lellansin 翻译.未经许可,禁止转载!英文出处:toptal.欢迎加入翻译组. 介绍 JavaScri ...
- CTSC2017总结
这个博客已经弃坑近一年了,自从去年国赛大力卡线进队后这近一年来我的情况从博客一年没更就可见一斑,OI水平原(zhi)地(xian)踏(fu)步(chong),炉石和双升的姿势水平倒是提高不少. 在经历 ...
随机推荐
- 利用if else 判断方程有几个根
static void Main(string[] args) { Console.ForegroundColor = ConsoleColor.Green; ...
- WordPress MORE+主题‘prettyPhoto’跨站脚本漏洞
漏洞名称: WordPress MORE+主题‘prettyPhoto’跨站脚本漏洞 CNNVD编号: CNNVD-201310-284 发布时间: 2013-10-23 更新时间: 2013-10- ...
- Mac 把图片反色
黑色图变白色 1:用预览打开 2:打开"调整颜色" 3:把"自动色阶"两边的按钮, 拖动换位置,就可以看到效果了.
- [pod install] error: cannot open .git/FETCH_HEAD: Permission denied
pod installAnalyzing dependencies[!] Pod::Executable pull error: cannot open .git/FETCH_HEAD: Permis ...
- SQL中and与or优先级比较
刚刚在项目中遇到这样一个问题,SQL语句如下: select * from LOAN_BACK_LIBRARY where LIBRARY_ID=1 or LIB_ID=1 and STATUS=3 ...
- android 使用android.support.v7 添加ActionBar
当需要在 android 7或更高的版本使用 ActionBar,则可以通过继承ActionBarActivity来实现, 网上有一个开源项目来兼容老版本显示ActionBar的效果:ActionBa ...
- SVN服务器及客户端的使用
Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址:http://s ...
- format 对整形的应用
对于整型数,会在整型值的前面以0补之 Format('this is %.7d'[1234]); 输出是:this is 0001234]
- Unix环境高级编程
1. windows下编辑的程序怎么上传到linux下执行? //Service vsftpd status查看linux ftp服务是否开启: Linuxi ip:192.168.40.128 打 ...
- sorts
各种排序算法: #include <stdio.h> #include <string.h> #include <ctype.h> #include <std ...