예제 #1
0
        /// <summary>
        /// Start a new server that listens for connections from anyone.
        /// </summary>
        /// <param name="name">The unique name of the server</param>
        /// <param name="resolver">For resolving custom message types received from the client</param>
        /// <param name="ipAddress">Determines which local network interface to use</param>
        /// <param name="udpGroupAddress">Optional request to setup UDP listener, pass null if you don't want that</param>
        /// <param name="udpGroupPort">Optional port required if you provide udpGroupAddress</param>
        /// <returns>Returns the new server object</returns>
        public static SmartSocketServer StartServer(string name, SmartSocketTypeResolver resolver,
                                                    string ipAddress       = "127.0.0.1",
                                                    string udpGroupAddress = "226.10.10.2",
                                                    int udpGroupPort       = 37992)
        {
            SmartSocketServer server = new SmartSocketServer(name, resolver, ipAddress, udpGroupAddress, udpGroupPort);

            server.StartListening();
            return(server);
        }
예제 #2
0
        internal SmartSocketClient(SmartSocketServer server, Socket client, SmartSocketTypeResolver resolver)
        {
            this.client    = client;
            this.stream    = new NetworkStream(client);
            this.server    = server;
            this.resolver  = resolver;
            client.NoDelay = true;

            DataContractSerializerSettings settings = new DataContractSerializerSettings();

            settings.DataContractResolver     = this.resolver;
            settings.PreserveObjectReferences = true;
            this.serializer = new DataContractSerializer(typeof(MessageWrapper), settings);
        }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SmartSocketServer"/> class.
 /// </summary>
 /// <param name="name">The name the client will check in UDP broadcasts to make sure it is connecting to the right server</param>
 /// <param name="resolver">A way of providing custom Message types for serialization</param>
 /// <param name="ipAddress">An optional ipAddress so you can decide which network interface to use</param>
 private SmartSocketServer(string name, SmartSocketTypeResolver resolver,
                           string ipAddress       = "127.0.0.1",
                           string udpGroupAddress = "226.10.10.2",
                           int udpGroupPort       = 37992)
 {
     this.serviceName = name;
     this.resolver    = resolver;
     this.ipAddress   = IPAddress.Parse(ipAddress);
     if (!string.IsNullOrEmpty(udpGroupAddress))
     {
         this.GroupAddress = IPAddress.Parse(udpGroupAddress);
         this.GroupPort    = udpGroupPort;
     }
 }
예제 #4
0
        /// <summary>
        /// Find a SmartSocketServer on the local network using UDP broadcast.  This will block
        /// waiting for a server to respond or until you cancel using the CancellationToken.
        /// </summary>
        /// <returns>The connected client or null if task is cancelled.</returns>
        public static async Task <SmartSocketClient> FindServerAsync(string serviceName, string clientName, SmartSocketTypeResolver resolver, CancellationToken token,
                                                                     string udpGroupAddress = "226.10.10.2", int udpGroupPort = 37992)
        {
            return(await Task.Run(async() =>
            {
                string localHost = FindLocalHostName();
                if (localHost == null)
                {
                    return null;
                }
                while (!token.IsCancellationRequested)
                {
                    try
                    {
                        var groupAddr = IPAddress.Parse(udpGroupAddress);
                        IPEndPoint remoteEP = new IPEndPoint(groupAddr, udpGroupPort);
                        UdpClient udpClient = new UdpClient(0);
                        MemoryStream ms = new MemoryStream();
                        BinaryWriter writer = new BinaryWriter(ms);
                        writer.Write(serviceName.Length);
                        writer.Write(serviceName);
                        byte[] bytes = ms.ToArray();
                        udpClient.Send(bytes, bytes.Length, remoteEP);

                        CancellationTokenSource receiveTaskSource = new CancellationTokenSource();
                        Task <UdpReceiveResult> receiveTask = udpClient.ReceiveAsync();
                        if (receiveTask.Wait(5000, receiveTaskSource.Token))
                        {
                            UdpReceiveResult result = receiveTask.Result;
                            IPEndPoint serverEP = result.RemoteEndPoint;
                            byte[] buffer = result.Buffer;
                            BinaryReader reader = new BinaryReader(new MemoryStream(buffer));
                            int len = reader.ReadInt32();
                            string addr = reader.ReadString();
                            string[] parts = addr.Split(':');
                            if (parts.Length == 2)
                            {
                                var a = IPAddress.Parse(parts[0]);
                                SmartSocketClient client = await ConnectAsync(new IPEndPoint(a, int.Parse(parts[1])), clientName, resolver);
                                if (client != null)
                                {
                                    client.ServerName = serviceName;
                                    client.Name = localHost;
                                    return client;
                                }
                            }
                        }
                        else
                        {
                            receiveTaskSource.Cancel();
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Something went wrong with Udp connection: " + ex.Message);
                    }
                }
                return null;
            }));
        }
예제 #5
0
        internal static async Task <SmartSocketClient> ConnectAsync(IPEndPoint serverEP, string clientName, SmartSocketTypeResolver resolver)
        {
            Socket client               = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            bool   connected            = false;
            CancellationTokenSource src = new CancellationTokenSource();

            try
            {
                Task task = Task.Run(() =>
                {
                    try
                    {
                        client.Connect(serverEP);
                        connected = true;
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine("Connect exception: " + e.Message);
                    }
                }, src.Token);

                // give it 30 seconds to connect...
                if (!task.Wait(60000))
                {
                    src.Cancel();
                }
            }
            catch (TaskCanceledException)
            {
                // move on...
            }

            if (connected)
            {
                var result = new SmartSocketClient(null, client, resolver)
                {
                    Name       = clientName,
                    ServerName = GetHostName(serverEP.Address)
                };
                SocketMessage response = await result.SendReceiveAsync(new SocketMessage(ConnectedMessageId, clientName));

                return(result);
            }

            return(null);
        }