Пример #1
0
        // Method: server listening to client request.
        public void StartListening()
        {
            // Establish the local endpoint for the socket
            // using the DNS name of the local computer.
            _ipHostInfo    = Dns.GetHostEntry(Dns.GetHostName());
            _ipAddress     = _ipHostInfo.AddressList[0];
            _localEndPoint = new IPEndPoint(_ipAddress, 3000);
            // Proxy endpoint.
            _proxyEndPoint = new IPEndPoint(_ipAddress, 4000);

            // New socket to connect with proxy.
            Socket proxySocket = new Socket(_ipAddress.AddressFamily,
                                            SocketType.Stream, ProtocolType.Tcp);

            // Create a TCP/IP socket to listen for connections.
            Socket listener = new Socket(_ipAddress.AddressFamily,
                                         SocketType.Stream, ProtocolType.Tcp);

            try
            {
                // Bind the socket to the local endpoint and
                // listen for incoming connections.
                listener.Bind(_localEndPoint);
                listener.Listen(100);

                // Create a new thread just for checking clients' status.
                Thread checkThread = new Thread(TestClientStatus);
                checkThread.Name         = "check thread";
                checkThread.IsBackground = true;
                checkThread.Start();

                // Name main thread.
                Thread.CurrentThread.Name = "main thread";

                // Connect with proxy
                proxySocket.Connect(_proxyEndPoint);
                _proxyConnection = new ClientConnection(proxySocket);

                // Make a new thread to maintain proxy connection.
                Thread proxyThread = new Thread(ProxyCommunicate);
                proxyThread.Name         = "proxy thread";
                proxyThread.IsBackground = true;
                proxyThread.Start();

                // Add main hall to list of chat room.
                _localCR.Add(_mainHall);
                while (true)
                {
                    Console.WriteLine("Waiting for a connection...");

                    // Start an asynchronous socket to handle client request.
                    // Program will pause here until request accepted.
                    Socket handler = listener.Accept();

                    // Once accepted, create a ClientConnection object
                    // and a UserInfo object to contain that particular
                    // user information.
                    ClientConnection clientState = new ClientConnection(handler);
                    UserInfo         newUser     = new UserInfo(clientState);

                    // Assign name for connected client.
                    newUser.UserName = "******" + _clientCount.ToString();
                    clientState.GetUser(newUser);

                    // Update server's client list.
                    _userList.Add(newUser);

                    // Add user to main hall.
                    _mainHall.AddUser(newUser);

                    // Update user's current room = main hall.
                    newUser.CurrentChatRoom = _mainHall;

                    _clientCount++;

                    // Create new thread to asynchronously handle client request.
                    Thread clientThread = new Thread(RequestHandler);
                    clientThread.Start(clientState);

                    // Name the thread after client name.
                    clientThread.Name = newUser.UserName;
                    // Set the thread to be running in background.
                    clientThread.IsBackground = true;

                    // This thread (main thread) will pause here until the client
                    // thread created above signal that it has created successfully.
                    _mainThread.WaitOne();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                // Informing proxy that this server is going offline.
                _packetSent.title   = MsgTitle.server_off.ToString();
                _packetSent.sender  = this.ServerName;
                _packetSent.content = null;

                foreach (var entry in _peerServerDict.Values)
                {
                    _packetSent.IP = entry.ClientSocket.LocalEndPoint.ToString();
                    entry.sendMsg(_packetSent);
                }
                _proxyConnection.sendMsg(_packetSent);
                // Shutdown listening socket.
                listener.Shutdown(SocketShutdown.Both);
                listener.Close();
            }
            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();
        }
Пример #2
0
        // Method: maintaining communication with proxy.
        // Executed on separated thread.
        private void ProxyCommunicate()
        {
            // Inform proxy that this server is on.
            _packetSent.title = MsgTitle.server_on.ToString();
            _packetSent.time  = _now;

            // use local EP of this server so that proxy can send this EP
            // to other servers, then they can connect to this server.
            _packetSent.IP      = _localEndPoint.ToString();
            _packetSent.content = null;
            _packetSent.sender  = this.ServerName;

            _proxyConnection.sendMsg(_packetSent);
            Console.WriteLine("proxy is online");

            bool notDone = true;

            try
            {
                // Begin receiving info from proxy.
                while (notDone)
                {
                    int    bytesRec  = _proxyConnection.ClientSocket.Receive(_proxyConnection.ReceiveBuffer);
                    string stringRec = Encoding.ASCII.GetString(_proxyConnection.ReceiveBuffer, 0, bytesRec);

                    var serializer       = new JavaScriptSerializer();
                    var serializedResult = serializer.Deserialize <Packet>(stringRec);
                    _packetReceived = serializedResult;
                    //Console.WriteLine(_packetReceived.content);
                    //Console.WriteLine(_packetReceived.IP);
                    //Console.WriteLine(_packetReceived.sender);
                    //Console.WriteLine(_packetReceived.title);

                    // When proxy is checking whether this server is still online.
                    if (_packetReceived.title.Equals(MsgTitle.are_you_online.ToString()))
                    {
                        // Inform proxy that this server is still online.
                        _packetSent.title   = MsgTitle.online.ToString();
                        _packetSent.time    = _now;
                        _packetSent.IP      = _proxyConnection.ClientSocket.LocalEndPoint.ToString();
                        _packetSent.content = "online";
                        _packetSent.sender  = this.ServerName;

                        _proxyConnection.sendMsg(_packetSent);
                    }
                    // Proxy inform that there is a new server online.
                    else if (_packetReceived.title.Equals(MsgTitle.server_on.ToString()))
                    {
                        // content will be name of server online
                        // IP is the IP of that server.
                        // create new thread and call the servercommunicate function
                        // create/update server ClientConnection
                        //Console.WriteLine("sender is " + _packetReceived.sender);

                        // New socket to connect with proxy.
                        Socket serverSocket = new Socket(_ipAddress.AddressFamily,
                                                         SocketType.Stream, ProtocolType.Tcp);
                        // Generate endpoint for server.
                        IPEndPoint remoteEP = createIPEndPoint(_packetReceived.IP);
                        serverSocket.Connect(remoteEP);
                        // Create new instance of ClientConnection to hold info.
                        ClientConnection newServerConn = new ClientConnection(serverSocket);
                        UserInfo         serverInfo    = new UserInfo(newServerConn);
                        newServerConn.GetUser(serverInfo);
                        newServerConn.Name = _packetReceived.content;

                        // Add this server to server dict.
                        //Console.WriteLine("content " + _packetReceived.content);
                        _peerServerDict[_packetReceived.content] = newServerConn;

                        // Make a new thread to maintain servers connection.
                        Thread serverThread = new Thread(ServerCommunicate);
                        serverThread.Name = newServerConn.Name;
                        //Console.WriteLine(serverThread.Name);
                        serverThread.IsBackground = true;
                        serverThread.Start(newServerConn);
                    }
                    else if (_packetReceived.title.Equals(MsgTitle.server_off.ToString()))
                    {
                        // Content is the name of the server.
                        if (_peerServerDict.ContainsKey(_packetReceived.content))
                        {
                            _peerServerDict.Remove(_packetReceived.content);
                            Console.WriteLine("Server " + _packetReceived.content + " is offline");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                notDone = false;
            }
        }