Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SmartSocketServer"/> class.
        /// Construct a new SmartSocketServer.
        /// </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>
        /// <param name="udpGroupAddress">An optional UDP group address.</param>
        /// <param name="udpGroupPort">An optional UDP group port.</param>
        private SmartSocketServer(string name, SmartSocketTypeResolver resolver, string ipAddress = "127.0.0.1:0",
                                  string udpGroupAddress = "226.10.10.2", int udpGroupPort = 37992)
        {
            this.ServiceName = name;
            this.Resolver    = resolver;
            if (ipAddress.Contains(':'))
            {
                string[] parts = ipAddress.Split(':');
                if (parts.Length == 2 && int.TryParse(parts[1], out int port))
                {
                    this.IpAddress = new IPEndPoint(IPAddress.Parse(parts[0]), port);
                }
                else
                {
                    throw new ArgumentException("ipAddress is not a valid format");
                }
            }
            else
            {
                this.IpAddress = new IPEndPoint(IPAddress.Parse(ipAddress), 0);
            }

            if (!string.IsNullOrEmpty(udpGroupAddress))
            {
                this.GroupAddress = IPAddress.Parse(udpGroupAddress);
                this.GroupPort    = udpGroupPort;
            }
        }
Beispiel #2
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,
                                                    string udpGroupAddress = "226.10.10.2", int udpGroupPort = 37992)
        {
            if (string.IsNullOrEmpty(ipAddress))
            {
                ipAddress = "127.0.0.1:0";
            }

            SmartSocketServer server = new SmartSocketServer(name, resolver, ipAddress, udpGroupAddress, udpGroupPort);

            server.StartListening();
            return(server);
        }
Beispiel #3
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);
        }
Beispiel #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 is 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 is 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;
            }));
        }
Beispiel #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);
        }