蛙蛙推荐:用winsock和iocp api打造一个echo server
2008-07-15 00:19
351 查看
蛙蛙推荐:用winsock和iocp api打造一个echo server
摘要:上次给大家演示了在c#里如何使用iocp的相关api,这次我们结合winsock和iocp来做一个实际的例子,就是一个回显服务器。本示例是根据《windows网络编程技术》里的一个c++例子改变而成,其中费了不少功夫,请教了不少人,在此表示感谢,希望大家也能从中有所收获,尤其是和非托管代码打交道方面。当然本文只是一个示例程序,还有好多需要考虑的地方,比如有的地方可能会造成句柄泄漏,内存泄漏等。
这里用到了一些技术点,比如平台调用、反射,多线程等,当然还有iocp和winsock的api,及GCHandle,SafeHandle,Marshal类的使用等,不过相当多的东西,我上篇帖子讲的都很细了,如果对winsock api不了解可以查阅MSDN。也没什么技术难点,说几个细节的地方吧。
1、.net自带的System.Threading.NativeOverlapped类型是完全按照win32的Overlapped结构实现的,因为我们在WSASend和WSAReceive的时候想要传递更多的数据,而不只是一个重叠结构,所以我自己定义了一个WaOverlapped,在原有结构的末尾加了一个指针,指向一个自定义类的GC句柄,这样在工作线程里就可以拿到自定义的单IO数据了,这个是我想了N种办法不行后的一个可行的办法。
2、注意GCHandle在取到数据后不用的话记着Free掉,否则就有可能造成内存泄漏。
3、如果调用WSASend或者WSAReceive返回6的话,多半是你准备的单IO数据不对,6表示无效的句柄。
4、如果传递给WSASend或者WSAReceive的Overlapped没pin住,会抛异常的,等不到GetLastWin32Error,所以用GCHandle.Alloc(PerIoData.Overlapped, GCHandleType.Pinned)把它pin住。
5、这个类还没有进行各方面的优化,其中的单IO数据,socket等都可以做成对象池来重用,Accept还可以替换成AcceptEx来用一个现成的Socket来接受新的连接,而不是自动创建一个新的,还有缓冲区可以做成环状的,关于性能方面的优化,下次有机会再给大家做实验。
完整代码如下,windows2008打开不安全代码进行编译,然后可以用telnet进行测试。
using System;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32.SafeHandles;
namespace WawaSocket.Net.Iocp
小结:希望通过这3篇帖子能加深大家对c#开发windows上的网络应用的了解。
摘要:上次给大家演示了在c#里如何使用iocp的相关api,这次我们结合winsock和iocp来做一个实际的例子,就是一个回显服务器。本示例是根据《windows网络编程技术》里的一个c++例子改变而成,其中费了不少功夫,请教了不少人,在此表示感谢,希望大家也能从中有所收获,尤其是和非托管代码打交道方面。当然本文只是一个示例程序,还有好多需要考虑的地方,比如有的地方可能会造成句柄泄漏,内存泄漏等。
这里用到了一些技术点,比如平台调用、反射,多线程等,当然还有iocp和winsock的api,及GCHandle,SafeHandle,Marshal类的使用等,不过相当多的东西,我上篇帖子讲的都很细了,如果对winsock api不了解可以查阅MSDN。也没什么技术难点,说几个细节的地方吧。
1、.net自带的System.Threading.NativeOverlapped类型是完全按照win32的Overlapped结构实现的,因为我们在WSASend和WSAReceive的时候想要传递更多的数据,而不只是一个重叠结构,所以我自己定义了一个WaOverlapped,在原有结构的末尾加了一个指针,指向一个自定义类的GC句柄,这样在工作线程里就可以拿到自定义的单IO数据了,这个是我想了N种办法不行后的一个可行的办法。
2、注意GCHandle在取到数据后不用的话记着Free掉,否则就有可能造成内存泄漏。
3、如果调用WSASend或者WSAReceive返回6的话,多半是你准备的单IO数据不对,6表示无效的句柄。
4、如果传递给WSASend或者WSAReceive的Overlapped没pin住,会抛异常的,等不到GetLastWin32Error,所以用GCHandle.Alloc(PerIoData.Overlapped, GCHandleType.Pinned)把它pin住。
5、这个类还没有进行各方面的优化,其中的单IO数据,socket等都可以做成对象池来重用,Accept还可以替换成AcceptEx来用一个现成的Socket来接受新的连接,而不是自动创建一个新的,还有缓冲区可以做成环状的,关于性能方面的优化,下次有机会再给大家做实验。
完整代码如下,windows2008打开不安全代码进行编译,然后可以用telnet进行测试。
using System;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32.SafeHandles;
namespace WawaSocket.Net.Iocp
小结:希望通过这3篇帖子能加深大家对c#开发windows上的网络应用的了解。
相关文章推荐
- 蛙蛙推荐:用winsock和iocp api打造一个echo server
- 推荐一个有API和汇编的视频教程 站
- 蛙蛙推荐:怎样获取一个表中所有字段的信息
- 【蛙蛙推荐】GridView和ObjectDataSource更新数据的一个Bug
- 一个简单的Echo Server的Java实现(增强版)
- 蛙蛙推荐:用VBS写了一个字符串实用函数的类
- 蛙蛙推荐:怎样获取一个表中所有字段的信息
- 蛙蛙推荐:用javascript作一个通用向导
- 蛙蛙推荐:自己架设一个邮件服务器
- TSQLDBServerHttpApi一个使用HTTPS.SYS内核的数据库服务端控件
- 蛙蛙推荐:作一个支持过载自适应和动态扩容的负载均衡服务
- Google 正在打造一个可统领所有网页操作的 Web Intents API
- 蛙蛙推荐:设计一个高效的网络服务器用户管理类
- 不要迷信API(单链表的另一种算法)——完成端口通讯服务器(IOCP Socket Server)设计(三)
- 蛙蛙推荐:设计一个高效的缓存管理服务
- 推荐一个.net下学习水晶报表的好程序兼ms sql server的好助手
- 打造一个安全的Win2003 Server服务器
- 推荐一个.net下学习水晶报表的好程序兼ms sql server的好助手
- 推荐一个前端开发的使用服务器环境开源项目 D2Server 可替代Apache
- 蛙蛙推荐:编写一个服务监控的软件