您的位置:首页 > 其它

蛙蛙推荐:用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上的网络应用的了解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: