110,534
社区成员
发帖
与我相关
我的任务
分享
public class ProtocolConst
{
public static int InitBufferSize = 1024; //解析命令初始缓存大小
public static int ReceiveBufferSize = 1024; //IOCP接收数据缓存大小,设置过小会造成事件响应增多,设置过大会造成内存占用偏多
}
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode, AsyncCallback callback, object state)
{
errorCode = this.DoBeginReceive(buffer, offset, size, socketFlags, asyncResult);
}
private SocketError DoBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
{
SocketError socketError = SocketError.SocketError;
try
{
asyncResult.SetUnmanagedStructures(buffer, offset, size, null, false, ref this.Caches.ReceiveOverlappedCache);
socketError = UnsafeNclNativeMethods.OSSOCK.WSARecv(this.m_Handle, ref asyncResult.m_SingleBuffer, 1, out num, ref socketFlags, asyncResult.OverlappedHandle, IntPtr.Zero);
}
finally
{
socketError = asyncResult.CheckAsyncCallOverlappedResult(socketError);
}
}
internal void SetUnmanagedStructures(byte[] buffer, int offset, int size, SocketAddress socketAddress, bool pinSocketAddress, ref OverlappedCache overlappedCache)
{
this.SetUnmanagedStructures(buffer, offset, size, socketAddress, pinSocketAddress);
}
internal void SetUnmanagedStructures(byte[] buffer, int offset, int size, SocketAddress socketAddress, bool pinSocketAddress)
{
if (pinSocketAddress && (this.m_SocketAddress != null))
{
base.SetUnmanagedStructures(objectsToPin);
}
else
{
base.SetUnmanagedStructures(buffer);
}
}
internal void SetUnmanagedStructures(object objectsToPin)
{
Socket asyncObject = (Socket) base.AsyncObject;
if (this.m_UseOverlappedIO)
{
}
else
{
asyncObject.BindToCompletionPort();
}
}
}
http://msdn.microsoft.com/zh-cn/magazine/cc163356.aspx中提到BeginXXX的性能问题出在两个方面,一是IAsyncResult不可复用,二是调用路径比较深(程序繁琐)。2.0 版本的 Socket 类使用 Windows I/O 完成端口来完成异步 I/O 操作。
当然不可否认.NET2.0中的IOCP装封有性能问题比较大。
在贴一段.NET2.0源代码public bool ReceiveAsync(SocketAsyncEventArgs e)
{
this.BindToCompletionPort();
SocketFlags socketFlags = e.m_SocketFlags;
try
{
if (e.m_Buffer != null)
{
error = UnsafeNclNativeMethods.OSSOCK.WSARecv(this.m_Handle, ref e.m_WSABuffer, 1, out num, ref socketFlags, e.m_PtrNativeOverlapped, IntPtr.Zero);
}
else
{
error = UnsafeNclNativeMethods.OSSOCK.WSARecv(this.m_Handle, e.m_WSABufferArray, e.m_WSABufferArray.Length, out num, ref socketFlags, e.m_PtrNativeOverlapped, IntPtr.Zero);
}
}
catch (Exception exception)
{
e.Complete();
throw exception;
}
}
这段代码我删除了一些无关代码,其它子调用我也懒得贴了。[/quote]2.0 版本的 Socket 类使用 Windows I/O 完成端口来完成异步 I/O 操作。
当然不可否认.NET2.0中的IOCP装封有性能问题比较大。
在贴一段.NET2.0源代码public bool ReceiveAsync(SocketAsyncEventArgs e)
{
this.BindToCompletionPort();
SocketFlags socketFlags = e.m_SocketFlags;
try
{
if (e.m_Buffer != null)
{
error = UnsafeNclNativeMethods.OSSOCK.WSARecv(this.m_Handle, ref e.m_WSABuffer, 1, out num, ref socketFlags, e.m_PtrNativeOverlapped, IntPtr.Zero);
}
else
{
error = UnsafeNclNativeMethods.OSSOCK.WSARecv(this.m_Handle, e.m_WSABufferArray, e.m_WSABufferArray.Length, out num, ref socketFlags, e.m_PtrNativeOverlapped, IntPtr.Zero);
}
}
catch (Exception exception)
{
e.Complete();
throw exception;
}
}
这段代码我删除了一些无关代码,其它子调用我也懒得贴了。[DllImport("ws2_32.dll", SetLastError=true)]
internal static extern SocketError WSARecv([In] SafeCloseSocket socketHandle, [In, Out] ref WSABuffer buffer, [In] int bufferCount, out int bytesTransferred, [In, Out] ref SocketFlags socketFlags, [In] IntPtr overlapped, [In] IntPtr completionRoutine);
BeginSend与SendAsync调用的是[DllImport("ws2_32.dll", SetLastError=true)]
internal static extern SocketError WSASend([In] SafeCloseSocket socketHandle, [In] ref WSABuffer buffer, [In] int bufferCount, out int bytesTransferred, [In] SocketFlags socketFlags, [In] IntPtr overlapped, [In] IntPtr completionRoutine);
是包装了IOCP调用的[/quote]
这个能说明是完成端口嘛??这个只是重叠IO。
WSASend WSARecv 这个是出现sp2中的。重叠IO只是完成端口的基础。[DllImport("ws2_32.dll", SetLastError=true)]
internal static extern SocketError WSARecv([In] SafeCloseSocket socketHandle, [In, Out] ref WSABuffer buffer, [In] int bufferCount, out int bytesTransferred, [In, Out] ref SocketFlags socketFlags, [In] IntPtr overlapped, [In] IntPtr completionRoutine);
BeginSend与SendAsync调用的是[DllImport("ws2_32.dll", SetLastError=true)]
internal static extern SocketError WSASend([In] SafeCloseSocket socketHandle, [In] ref WSABuffer buffer, [In] int bufferCount, out int bytesTransferred, [In] SocketFlags socketFlags, [In] IntPtr overlapped, [In] IntPtr completionRoutine);
是包装了IOCP调用的