예제 #1
0
        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, (nuint)(ulong)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.ModeDefault);
        }
예제 #2
0
        static void OnCallback(IntPtr s, nuint type, IntPtr address, IntPtr data, IntPtr info)
        {
            var socket = GCHandle.FromIntPtr(info).Target as CFSocket;

            if (socket is null)
            {
                return;
            }
            CFSocketCallBackType cbType = (CFSocketCallBackType)(ulong)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
                {
                    // Note that we read a 32bit value even if CFSocketError is a nint:
                    // 'or a pointer to an SInt32 error code if the connect failed.'
                    result = (CFSocketError)Marshal.ReadInt32(data);
                }
                socket.OnConnect(new CFSocketConnectEventArgs(result));
            }
            else if (cbType == CFSocketCallBackType.DataCallBack)
            {
                var ep = CFSocketAddress.EndPointFromAddressPtr(address);
                using (var cfdata = new CFData(data, false))
                    socket.OnData(new CFSocketDataEventArgs(ep, cfdata.GetBuffer()));
            }
            else if (cbType == CFSocketCallBackType.NoCallBack)
            {
                // nothing to do
            }
            else if (cbType == CFSocketCallBackType.ReadCallBack)
            {
                socket.OnRead(new CFSocketReadEventArgs());
            }
            else if (cbType == CFSocketCallBackType.WriteCallBack)
            {
                socket.OnWrite(new CFSocketWriteEventArgs());
            }
        }
예제 #3
0
        CFSocket(CFSocketNativeHandle sock)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack;

            gch = GCHandle.Alloc(this);
            try {
                var ctx = new CFStreamClientContext();
                ctx.Info = GCHandle.ToIntPtr(gch);

                var handle = CFSocketCreateWithNative(IntPtr.Zero, sock, (nuint)(ulong)cbTypes, OnCallback, ref ctx);
                InitializeHandle(handle);

                var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0), true);
                var loop   = CFRunLoop.Current;
                loop.AddSource(source, CFRunLoop.ModeDefault);
            } catch {
                gch.Free();
                throw;
            }
        }
예제 #4
0
 public CFSocketAcceptEventArgs(CFSocketNativeHandle handle, IPEndPoint remote)
 {
     this.SocketHandle   = handle;
     this.RemoteEndPoint = remote;
 }
예제 #5
0
 extern static IntPtr CFSocketCreateWithNative(IntPtr allocator, CFSocketNativeHandle sock,
                                               nuint /*CFOptionFlags*/ callBackTypes,
                                               CFSocketCallBack callout, ref CFStreamClientContext ctx);
예제 #6
0
 internal extern static void CFStreamCreatePairWithSocket(/* CFAllocatorRef */ IntPtr allocator, CFSocketNativeHandle sock,
                                                          /* CFReadStreamRef* */ out IntPtr readStream, /* CFWriteStreamRef* */ out IntPtr writeStream);