internal CFSocket(CFSocketNativeHandle sock) { var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack; gch = GCHandle.Alloc(this); var ctx = new CFStreamClientContext(); ctx.Info = GCHandle.ToIntPtr(gch); var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CFStreamClientContext))); try { Marshal.StructureToPtr(ctx, ptr, false); Handle = CFSocketCreateWithNative( IntPtr.Zero, sock, cbTypes, OnCallback, ptr); } finally { Marshal.FreeHGlobal(ptr); } if (Handle == IntPtr.Zero) { throw new CFSocketException(CFSocketError.Error); } var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, Handle, 0)); var loop = CFRunLoop.Current; loop.AddSource(source, CFRunLoop.CFDefaultRunLoopMode); }
static void OnCallback(IntPtr s, int type, IntPtr address, IntPtr data, IntPtr info) { var socket = GCHandle.FromIntPtr(info).Target as CFSocket; CFSocketCallBackType cbType = (CFSocketCallBackType)type; if (cbType == CFSocketCallBackType.AcceptCallBack) { var ep = CFSocketAddress.EndPointFromAddressPtr(address); var handle = new CFSocketNativeHandle(Marshal.ReadInt32(data)); socket.OnAccepted(new CFSocketAcceptEventArgs(handle, ep)); } else if (cbType == CFSocketCallBackType.ConnectCallBack) { CFSocketError result; if (data == IntPtr.Zero) { result = CFSocketError.Success; } else { result = (CFSocketError)Marshal.ReadInt32(data); } socket.OnConnect(new CFSocketConnectEventArgs(result)); } }
static extern void CFStreamCreatePairWithSocket(IntPtr allocator, CFSocketNativeHandle socket, out IntPtr read, out IntPtr write);
public CFSocketAcceptEventArgs(CFSocketNativeHandle handle, IPEndPoint remote) { this.SocketHandle = handle; this.RemoteEndPoint = remote; }
extern static IntPtr CFSocketCreateWithNative(IntPtr allocator, CFSocketNativeHandle sock, CFSocketCallBackType callBackTypes, CFSocketCallBack callout, IntPtr ctx);
extern static void CFStreamCreatePairWithSocket(IntPtr allocator, CFSocketNativeHandle socket, out IntPtr read, out IntPtr write);
public CFSocketAcceptEventArgs (CFSocketNativeHandle handle, IPEndPoint remote) { this.SocketHandle = handle; this.RemoteEndPoint = remote; }
internal CFSocket (CFSocketNativeHandle sock) { var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack; gch = GCHandle.Alloc (this); var ctx = new CFStreamClientContext (); ctx.Info = GCHandle.ToIntPtr (gch); var ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof(CFStreamClientContext))); try { Marshal.StructureToPtr (ctx, ptr, false); handle = CFSocketCreateWithNative ( IntPtr.Zero, sock, cbTypes, OnCallback, ptr); } finally { Marshal.FreeHGlobal (ptr); } if (handle == IntPtr.Zero) throw new CFSocketException (CFSocketError.Error); var source = new CFRunLoopSource (CFSocketCreateRunLoopSource (IntPtr.Zero, handle, 0)); var loop = CFRunLoop.Current; loop.AddSource (source, CFRunLoop.CFDefaultRunLoopMode); }
extern static IntPtr CFSocketCreateWithNative (IntPtr allocator, CFSocketNativeHandle sock, CFSocketCallBackType callBackTypes, CFSocketCallBack callout, IntPtr ctx);
static void OnCallback (IntPtr s, int type, IntPtr address, IntPtr data, IntPtr info) { var socket = GCHandle.FromIntPtr (info).Target as CFSocket; CFSocketCallBackType cbType = (CFSocketCallBackType)type; if (cbType == CFSocketCallBackType.AcceptCallBack) { var ep = CFSocketAddress.EndPointFromAddressPtr (address); var handle = new CFSocketNativeHandle (Marshal.ReadInt32 (data)); socket.OnAccepted (new CFSocketAcceptEventArgs (handle, ep)); } else if (cbType == CFSocketCallBackType.ConnectCallBack) { CFSocketError result; if (data == IntPtr.Zero) result = CFSocketError.Success; else result = (CFSocketError)Marshal.ReadInt32 (data); socket.OnConnect (new CFSocketConnectEventArgs (result)); } }