深入探讨C#中Socket一次性搞定消息发送
2013-10-28 17:25
316 查看
转载自:http://tech.chinaunix.net/a2010/0909/1101/000001101396.shtml
【IT168 技术文档】最近浏览了几篇有关Socket发送消息的文章,发现大家对Socket Send方法理解有所偏差,现将自己在开发过程中对Socket的领悟写出来,以供大家参考。
(一)架构
基于TCP协议的Socket通信,架构类似于B/S架构,一个Socket通信服务器,多个Socket通信客户端。Socket通信服务器启动时,会建立一个侦听Socket,侦听Socket将侦听到的Socket连接传给接受Socket,然后由接受Socket完成接受、发送消息,当Socket存在异常时,断开连接。在实际开发项目中,往往要求Socket通信服务器能提供高效、稳定的服务,一般会用到以下技术:双工通信、完成端口、SAEA、池、多线程、异步等。特别是池,用的比较多,池一般包括一下几种:
1)Buffer池,用于集中管控Socket缓冲区,防止内存碎片。
2)SAEA池,用于集中管控Socket,重复利用Socket。
3)SQL池,用于分离网络服务层与数据访问层(SQL的执行效率远远低于网络层执行效率)
(二)Send
主服务器接受Socket为一端口,客户端Socket为一端口,这两个端口通过TCP协议建立连接,通信基础系统负责管理此连接,它有两个功能:
1)发送消息
2)接受消息
Socket的Send方法,并非大家想象中的从一个端口发送消息到另一个端口,它仅仅是拷贝数据到基础系统的发送缓冲区,然后由基础系统将发送缓冲区的数据到连接的另一端口。值得一说的是,这里的拷贝数据与异步发送消息的拷贝是不一样的,同步发送的拷贝,是直接拷贝数据到基础系统缓冲区,拷贝完成后返回,在拷贝的过程中,执行线程会IO等待, 此种拷贝与Socket自带的Buffer空间无关,但异步发送消息的拷贝,是将Socket自带的Buffer空间内的所有数据,拷贝到基础系统发送缓冲区,并立即返回,执行线程无需IO等待,所以异步发送在发送前必须执行SetBuffer方法,拷贝完成后,会触发你自定义回调函数ProcessSend,在ProcessSend方法中,调用SetBuffer方法,重新初始化Buffer空间。
口说无凭,下面给个例子:
服务器端:
客户端:
解释:
客户端第一次发送数据:1234567890。
客户端第一个接受数据:1234567890,该数据由服务端用Send同步方法发送返回。
客户端第二个接受数据:1234567890,该数据由服务端用Send异步方法发送返回。
以上似乎没什么异常,好,接下来,我只发送abc。
客户端第一个接受数据:abc,理所当然,没什么问题。
客户端第二个接受数据:abc4567890!为什么呢?应该是abc才对呀!
好,现在为大家解释一下:
异步发送是将其Buffer空间中所有数据拷贝到基础系统发送缓冲区,第一次拷贝1234567890到发送缓冲区,所以收到1234567890,第二次拷贝abc到发送缓冲区,替换了先前的123,所以收到abc4567890,大家明白的?
【IT168 技术文档】最近浏览了几篇有关Socket发送消息的文章,发现大家对Socket Send方法理解有所偏差,现将自己在开发过程中对Socket的领悟写出来,以供大家参考。
(一)架构
基于TCP协议的Socket通信,架构类似于B/S架构,一个Socket通信服务器,多个Socket通信客户端。Socket通信服务器启动时,会建立一个侦听Socket,侦听Socket将侦听到的Socket连接传给接受Socket,然后由接受Socket完成接受、发送消息,当Socket存在异常时,断开连接。在实际开发项目中,往往要求Socket通信服务器能提供高效、稳定的服务,一般会用到以下技术:双工通信、完成端口、SAEA、池、多线程、异步等。特别是池,用的比较多,池一般包括一下几种:
1)Buffer池,用于集中管控Socket缓冲区,防止内存碎片。
2)SAEA池,用于集中管控Socket,重复利用Socket。
3)SQL池,用于分离网络服务层与数据访问层(SQL的执行效率远远低于网络层执行效率)
(二)Send
主服务器接受Socket为一端口,客户端Socket为一端口,这两个端口通过TCP协议建立连接,通信基础系统负责管理此连接,它有两个功能:
1)发送消息
2)接受消息
Socket的Send方法,并非大家想象中的从一个端口发送消息到另一个端口,它仅仅是拷贝数据到基础系统的发送缓冲区,然后由基础系统将发送缓冲区的数据到连接的另一端口。值得一说的是,这里的拷贝数据与异步发送消息的拷贝是不一样的,同步发送的拷贝,是直接拷贝数据到基础系统缓冲区,拷贝完成后返回,在拷贝的过程中,执行线程会IO等待, 此种拷贝与Socket自带的Buffer空间无关,但异步发送消息的拷贝,是将Socket自带的Buffer空间内的所有数据,拷贝到基础系统发送缓冲区,并立即返回,执行线程无需IO等待,所以异步发送在发送前必须执行SetBuffer方法,拷贝完成后,会触发你自定义回调函数ProcessSend,在ProcessSend方法中,调用SetBuffer方法,重新初始化Buffer空间。
口说无凭,下面给个例子:
服务器端:
客户端:
解释:
客户端第一次发送数据:1234567890。
客户端第一个接受数据:1234567890,该数据由服务端用Send同步方法发送返回。
客户端第二个接受数据:1234567890,该数据由服务端用Send异步方法发送返回。
以上似乎没什么异常,好,接下来,我只发送abc。
客户端第一个接受数据:abc,理所当然,没什么问题。
客户端第二个接受数据:abc4567890!为什么呢?应该是abc才对呀!
好,现在为大家解释一下:
异步发送是将其Buffer空间中所有数据拷贝到基础系统发送缓冲区,第一次拷贝1234567890到发送缓冲区,所以收到1234567890,第二次拷贝abc到发送缓冲区,替换了先前的123,所以收到abc4567890,大家明白的?
相关文章推荐
- C# new用法总结-转
- (转)c# 筛选数组重复项
- C#中New关键词的几种用法
- c#中抽象类和接口的详细介绍
- C# 判断窗体是否打开 如果打开激活窗体 两种方法
- C#反射详解
- C# 调试程序时如何输入命令行参数
- override(C# 参考)
- 遇到的问题-----------c#在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 遇到的问题-----------c#在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- C#操作word的一些基本方法(word打印,插入文件,插入图片,定位页眉页脚,去掉横线)
- 在C#代码中应用Log4Net(三)Log4Net中配置文件的解释
- C# .NET treeView(树形控件)绑定数据的通用方法 (精)
- C# 中using 用来释放资源的用法
- C#中Lambda表达式
- c#中的抽象类和接口
- C# File, FileInfo, Directory, DirectoryInfo的区别
- C#获取项目程序路径的方法
- C# 降低图片的质量
- C#中ToString格式大全