コード例 #1
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        private void ReceiveCallback(IAsyncResult target)
        {
            Logger.WriteLine("--- ReceiveCallback");
            Message.MessageType requestType = Message.MessageType.Unknown;
            Socket handler = null;
            try
            {
                object[] obj = new object[2];
                obj = (object[])target.AsyncState;

                byte[] buffer = (byte[]) obj[0];
                handler = (Socket) obj[1];

                Logger.WriteLine("ReceiveCallback from " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);

                bool quit = false;

                int bytesRead = handler.EndReceive(target);
                if (bytesRead > 0)
                {
                    Message request = new Message(buffer);
                    Message response;

                    requestType = request.GetMessageType();
                    if (requestType == Message.MessageType.HandshakePeerCreator) // Peer client mau join ke room ini
                    {
                        #region Handshake
                        Logger.WriteLine("HandshakePeerCreator");
                        if (Room.Members.Count < Room.MaxPlayer)
                        {
                            int newPeerId, newPeerListenPort;
                            IPAddress newPeerIp = (handler.RemoteEndPoint as IPEndPoint).Address;
                            request.GetHandshakePeerCreator(out newPeerId, out newPeerListenPort);
                            Room.Members.Add(new Peer(newPeerId, newPeerIp, newPeerListenPort));

                            Logger.WriteLine("Peer ID : " + newPeerId);
                            Logger.WriteLine("Peer IP : " + newPeerIp + ":" + newPeerListenPort);

                            // Send SUCCESS message
                            response = Message.CreateMessageSuccess();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);

                            if (nextPeerSocket != null)
                            {
                                Logger.WriteLine("Sending NEW MEMBER to nextPeerSocket: " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                                // Send NewMember message to next peer
                                response = Message.CreateMessageNewMember(newPeerId, (handler.RemoteEndPoint as IPEndPoint).Address, newPeerListenPort);
                                nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                            else
                            {
                                IPEndPoint ipEndPoint = new IPEndPoint(newPeerIp, newPeerListenPort);
                                nextPeerSocket = new Socket(
                                    newPeerIp.AddressFamily,
                                    SocketType.Stream,
                                    ProtocolType.Tcp
                                   );
                                nextPeerSocket.NoDelay = false;
                                nextPeerSocket.Connect(ipEndPoint);

                                Logger.WriteLine("Setting up nextPeerSocket to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);

                                response = Message.CreateMessageRoomModel(Room);
                                nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                Logger.WriteLine("Send room info");

                                keepAliveRoom = new Thread(new ThreadStart(SendAliveNextPeer));
                                keepAliveRoom.Start();
                            }

                            response = Message.CreateMessageAdd(newPeerId, Room.RoomId);
                            lock (trackerPaddle)
                            {
                                trackerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                byte[] bufferRecv = new byte[1024];
                                trackerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            Logger.WriteLine("Send FAILED: Room penuh");
                            // Send FAILED message akibat ruang penuh
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            handler.Close();
                            quit = true;
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.KeepAlive)
                    {
                        #region Keep Alive
                        int peerId;
                        request.GetKeepAlive(out peerId);
                        Peer peer = Room.Members.Find(fpeer => fpeer.PeerId == peerId);
                        if (peer != null)
                        {
                            //Send KeepAlive Message back
                            response = request;
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.NewMember)
                    {
                        #region NewMember
                        Logger.WriteLine("NewMember");
                        if (IsCreator)
                        {
                            Logger.WriteLine("NewMember has been received by peer creator");
                            Logger.WriteLine("Closing connection from " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);
                            handler.Close();
                            quit = true;
                        }
                        else
                        {
                            bool isLast = Room.Members.Last().PeerId == PeerId;

                            int newPeerId, newPeerListenPort;
                            IPAddress newPeerIp;
                            request.GetNewMember(out newPeerId, out newPeerIp, out newPeerListenPort);
                            Room.Members.Add(new Peer(newPeerId, newPeerIp, newPeerListenPort));

                            Logger.WriteLine("Sending NEW MEMBER to nextPeerSocket: " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                            response = request;
                            nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);

                            if (isLast)
                            {
                                Logger.WriteLine("Closing connection " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                                nextPeerSocket.Close();

                                IPEndPoint ipEndPoint = new IPEndPoint(newPeerIp, newPeerListenPort);
                                nextPeerSocket = new Socket(
                                    newPeerIp.AddressFamily,
                                    SocketType.Stream,
                                    ProtocolType.Tcp
                                   );

                                nextPeerSocket.NoDelay = false;
                                nextPeerSocket.Connect(ipEndPoint);

                                Logger.WriteLine("Setting up nextPeerSocket to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);

                                response = Message.CreateMessageRoomModel(Room);
                                nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                Logger.WriteLine("Send room info");
                            }
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.RoomModel)
                    {
                        #region Room
                        Logger.WriteLine("RoomModel");
                        Room room;
                        request.GetRoomModel(out room);
                        Room = room;
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Quit)
                    {
                        int peerId;
                        request.GetQuit(out peerId);
                        Peer peer = Room.Members.Find(fpeer => fpeer.PeerId == peerId);
                        byte[] bufferRecv;

                        if (Room.Members.Count != 2)
                        {
                            if (PeerId == peerId)
                            {
                                Logger.WriteLine("Quit done");
                            }
                            else
                            {
                                int i = 0;
                                for (; i < Room.Members.Count; i++)
                                {// i adalah indeks peer yang ingin quit
                                    if (Room.Members[i].PeerId == peerId)
                                    {
                                        break;
                                    }
                                }

                                int j = 0;
                                for (; j < Room.Members.Count; j++)
                                {// j adalah indeks current peer
                                    if (Room.Members[j].PeerId == PeerId)
                                    {
                                        break;
                                    }
                                }

                                if (j == i + 1 || (j == 0 && i == Room.Members.Count - 1)) // yg mau quit adalah peer sebelum current peer
                                {
                                    quit = true;
                                }

                                response = request;

                                lock (nextPeerPaddle)
                                {
                                    nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                    Logger.WriteLine("Forward Quit to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address);
                                    bufferRecv = new byte[1024];
                                    nextPeerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                                }

                                if (i == j + 1 || (i == 0 && j == Room.Members.Count - 1))// yg mau quit adalah peer setelah current peer
                                {
                                    nextPeerSocket.Close();
                                    IPAddress ip = Room.Members[(i + 1) % (Room.Members.Count - 1)].IPAddress;
                                    IPEndPoint ipEndPoint = new IPEndPoint(ip, Room.Members[(i + 1) % (Room.Members.Count - 1)].ListeningPort);
                                    nextPeerSocket = new Socket(
                                        ip.AddressFamily,
                                        SocketType.Stream,
                                        ProtocolType.Tcp
                                        );

                                    nextPeerSocket.NoDelay = false;
                                    nextPeerSocket.Connect(ipEndPoint);

                                    nextPeerSocket = null;
                                }

                                if (this.PeerId == Room.Creator.PeerId || (peerId == Room.Creator.PeerId && Room.Members[1].PeerId == this.PeerId))
                                {
                                    lock (trackerPaddle)
                                    {
                                        response = Message.CreateMessageRemove(peerId, PeerId, Configuration.ListenPort, Room.RoomId);
                                        trackerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);

                                        bufferRecv = new byte[1024];
                                        trackerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                                    }
                                }

                                if (peerId == Room.Creator.PeerId)
                                {
                                    Room.Creator = Room.Members[1];
                                }

                                response = Message.CreateMessageSuccess();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);

                                bufferRecv = new byte[1024];
                                nextPeerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            lock (trackerPaddle)
                            {
                                response = Message.CreateMessageRemove(peerId, PeerId, Configuration.ListenPort, Room.RoomId);
                                trackerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);

                                bufferRecv = new byte[1024];
                                trackerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                            }
                        }
                        Room.Members.Remove(peer);
                    }
                    else if (requestType == Message.MessageType.Start)
                    {
                        #region Start
                        Logger.WriteLine("Start");
                        int peerId;
                        string roomId;
                        request.GetStart(out peerId, out roomId);

                        Logger.WriteLine("Received START message with PeerId : " + peerId + " RoomId : " + roomId);

                        if (peerId == PeerId)
                        {
                            // do nothing
                            Logger.WriteLine("FINISHED");
                        }
                        else
                        {
                            // Send NewMember message to next peer
                            response = request;
                            nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            Logger.WriteLine("Forward START to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address);
                        }
                    }
                    else
                    {
                        Logger.WriteLine("Listener receive unknown message");
                        // Send FAILED message akibat ruang penuh
                        response = Message.CreateMessageFailed();
                        handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                    }
                        #endregion
                }

                if (!quit)
                {
                    IAsyncResult nextAsyncResult = handler.BeginReceive(
                        buffer,
                        0,
                        buffer.Length,
                        SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        obj
                    );

                    if (!nextAsyncResult.AsyncWaitHandle.WaitOne(Configuration.MaxTimeout))
                    {
                        Logger.WriteLine("Connection timeout for peer with IP Address " + (handler.LocalEndPoint as IPEndPoint).Address + ":" + (handler.LocalEndPoint as IPEndPoint).Port + " -> " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);
                        Logger.WriteLine("Closing connection " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);
                        handler.Close();
                    }
                }
            }
            catch (SocketException exc)
            {
                Logger.WriteLine(exc);
                if (exc.SocketErrorCode == SocketError.HostDown || exc.SocketErrorCode == SocketError.ConnectionReset)
                {
                    if (Room.Members.Count > 2)
                    {
                        int index = -1;
                        for (int i = 0; i < Room.Members.Count; i++)
                        {
                            Peer p = Room.Members[i];
                            if (p.IPAddress.Equals((handler.LocalEndPoint as IPEndPoint).Address))
                            {
                                index = i;
                            }
                        }

                        if (index == 0)
                        {
                            index = Room.Members.Count - 2;
                        }
                        else
                        {
                            index--;
                        }

                        Peer backPeer = Room.Members[index];
                        byte[] buffer = new byte[1024];
                        Message request = Message.CreateMessageQuit(backPeer.PeerId);
                        lock (nextPeerPaddle)
                        {
                            nextPeerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                            nextPeerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                        }
                    }
                    else
                    {
                        // Remove last element
                        Room.Members.RemoveAt(1);
                        lock (nextPeerPaddle)
                        {
                            nextPeerSocket = null;
                        }
                    }
                }
            }

            Logger.WriteLine();
        }
コード例 #2
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        private void SendAliveNextPeer()
        {
            try
            {
                while (true)
                {
                    Logger.WriteLine("SendAliveNextPeer");
                    byte[] buffer = new byte[1024];

                    lock (nextPeerPaddle)
                    {
                        if (nextPeerSocket == null)
                        {
                            Thread.Sleep(Configuration.MaxTimeout / 2);
                            continue;
                        }

                        Message mes = Message.CreateMessageKeepAlive(PeerId);
                        nextPeerSocket.Send(mes.data, 0, mes.data.Length, SocketFlags.None);
                        nextPeerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    if (response.GetMessageType() == Message.MessageType.KeepAlive)
                    {
                        Logger.WriteLine("KeepAlive to next peer success.");
                        Thread.Sleep(Configuration.MaxTimeout / 2);
                    }
                    else
                    {
                        Logger.WriteLine("Message KeepAlive reply from next peer has not been received.");
                        lock (nextPeerPaddle)
                        {
                            Logger.WriteLine("Closing connection " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                            nextPeerSocket.Close();
                        }
                        break;
                    }
                    Logger.WriteLine();
                }
            }
            catch (Exception e)
            {
                Logger.WriteLine(e.Message);
            }
        }
コード例 #3
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        public List<Message.MessageRoomBody> ListRooms()
        {
            try
            {
                Logger.WriteLine("Requesting to list room");

                Message messageOut = Message.CreateMessageList(PeerId);
                byte[] buffer = new byte[1024];

                trackerSocket.Send(messageOut.data, 0, messageOut.data.Length, SocketFlags.None);
                trackerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);

                Message messageIn = new Message(buffer);
                if (messageIn.GetMessageType() == Message.MessageType.Room)
                {
                    List<Message.MessageRoomBody> s;
                    messageIn.GetRoom(out s);
                    foreach (var a in s)
                    {
                        Logger.WriteLine("ROOM: " + a.roomId);
                    }
                    return s;
                }
                else
                {
                    Logger.WriteLine("Failed to list rooms");
                    return null;
                }
            }
            catch (Exception exc)
            {
                Logger.WriteLine(exc);
                return null;
            }
        }
コード例 #4
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        public void Quit()
        {
            try
            {
                if ((IsConnected) && (IsInRoom))
                {
                    Logger.WriteLine("Requesting to quit room");

                    Message request = Message.CreateMessageQuit(PeerId);
                    byte[] buffer = new byte[1024];

                    lock (nextPeerPaddle)
                    {
                        nextPeerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                        nextPeerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    Message.MessageType responseType = response.GetMessageType();
                    if (responseType == Message.MessageType.Success)
                    {
                        nextPeerSocket.Close();
                        nextPeerSocket = null;
                        listenerSocket.Disconnect(true);
                    }
                    else
                    {
                        Logger.WriteLine("Quit is prohibited");
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }
コード例 #5
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        public bool JoinRoom(string roomId)
        {
            try
            {
                if ((IsConnected) && (!IsInRoom))
                {
                    Logger.WriteLine("Requesting to join room " + roomId);
                    Message request = Message.CreateMessageJoin(PeerId, roomId);
                    byte[] buffer = new byte[1024];

                    lock (trackerPaddle)
                    {
                        trackerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                        trackerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    Message.MessageType responseType = response.GetMessageType();
                    if (responseType == Message.MessageType.CreatorInfo)
                    {
                        IPAddress ip;
                        int port;
                        response.GetCreatorInfo(out ip, out port);

                        Logger.WriteLine("GunbondPeer (Peer - Tracker): Creator Info");
                        Logger.WriteLine("Hostname : " + ip);
                        Logger.WriteLine("Port     : " + port);

                        SocketPermission permission = new SocketPermission(
                             NetworkAccess.Connect,
                             TransportType.Tcp,
                             "",
                             SocketPermission.AllPorts
                             );
                        permission.Demand();

                        byte[] bufferFromCreator = new byte[1024];

                        lock (nextPeerPaddle)
                        {
                            IPEndPoint ipEndPoint = new IPEndPoint(ip, port);
                            nextPeerSocket = new Socket(
                                ip.AddressFamily,
                                SocketType.Stream,
                                ProtocolType.Tcp
                                );

                            nextPeerSocket.NoDelay = false;
                            nextPeerSocket.Connect(ipEndPoint);
                            Message messageConnectToCreator = Message.CreateMessageHandshakePeerCreator(PeerId, Configuration.ListenPort);

                            nextPeerSocket.Send(messageConnectToCreator.data, 0, messageConnectToCreator.data.Length, SocketFlags.None);
                            nextPeerSocket.Receive(bufferFromCreator, bufferFromCreator.Length, SocketFlags.None);
                        }

                        keepAliveRoom = new Thread(new ThreadStart(SendAliveNextPeer));
                        keepAliveRoom.Start();

                        Message messageFromCreator = new Message(bufferFromCreator);
                        Message.MessageType fromCreatorMessageType = messageFromCreator.GetMessageType();
                        if (fromCreatorMessageType == Message.MessageType.Success)
                        {
                            IsInRoom = true;
                            IsCreator = false;

                            Logger.WriteLine("Successfully joined room.");
                            return true;
                        }
                        else
                        {
                            Logger.WriteLine("Request join room failed 1.");
                            return false;
                        }

                    }
                    else if (responseType == Message.MessageType.Failed)
                    {
                        Console.WriteLine("Request join room failed 2.");
                        return false;
                    }
                    else
                    {
                        Console.WriteLine("Response unrecognized.");
                        return false;
                    }
                }
                else if (!IsConnected)
                {
                    Console.WriteLine("Not connected to tracker, connect to tracker first.");
                    return false;
                }
                else if (IsInRoom)
                {
                    Console.WriteLine("Currently in room, quit room first.");
                    return false;
                }
                else
                {
                    Console.WriteLine("Unknown error.");
                    return false;
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
                return false;
            }
        }
コード例 #6
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        public bool CreateRoom(string roomId, int maxPlayers)
        {
            try
            {
                if (IsConnected && !IsInRoom)
                {
                    Logger.WriteLine("Requesting to create room");

                    byte[] buffer = new byte[1024];
                    Message request = Message.CreateMessageCreate(PeerId, maxPlayers, roomId, Configuration.ListenPort);

                    lock (trackerPaddle)
                    {
                        trackerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                        trackerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    Message.MessageType responseType = response.GetMessageType();
                    if (responseType == Message.MessageType.Success)
                    {
                        Logger.WriteLine("Request create room success: " + roomId);

                        Room = new Room(roomId, new Peer(PeerId, (trackerSocket.LocalEndPoint as IPEndPoint).Address, Configuration.ListenPort), maxPlayers);
                        Room.Members.Add(Room.Creator);

                        IsInRoom = true;
                        IsCreator = true;

                        return true;
                    }
                    else if (responseType == Message.MessageType.Failed)
                    {
                        Logger.WriteLine("Request create room failed.");
                        return false;
                    }
                    else
                    {
                        Logger.WriteLine("Response unrecognized.");
                        return false;
                    }
                }
                else if (!IsConnected)
                {
                    Logger.WriteLine("Not connected to tracker, connect to tracker first.");
                    return false;
                }
                else if (IsInRoom)
                {
                    Logger.WriteLine("Currently in room, quit room first.");
                    return false;
                }
                else
                {
                    Logger.WriteLine("Unknown error.");
                    return false;
                }
            }
            catch (Exception exc)
            {
                Logger.WriteLine(exc);
                return false;
            }
        }
コード例 #7
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        public bool ConnectTracker()
        {
            try
            {
                if (!IsConnected)
                {
                    SocketPermission permission = new SocketPermission(
                        NetworkAccess.Connect,
                        TransportType.Tcp,
                        "",
                        SocketPermission.AllPorts
                        );

                    permission.Demand();

                    IPAddress trackerAddr;
                    if (IPAddress.TryParse(Configuration.TrackerAddress, out trackerAddr))
                    {
                        byte[] buffer = new byte[1024];
                        lock (trackerPaddle)
                        {
                            IPEndPoint ipEndPoint = new IPEndPoint(trackerAddr, Configuration.Port);
                            trackerSocket = new Socket(
                                trackerAddr.AddressFamily,
                                SocketType.Stream,
                                ProtocolType.Tcp
                               );

                            trackerSocket.NoDelay = false;
                            trackerSocket.Connect(ipEndPoint);
                            Message request = Message.CreateMessageHandshakePeer();

                            trackerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                            trackerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                        }

                        Message response = new Message(buffer);
                        if (response.GetMessageType() == Message.MessageType.HandshakeTracker)
                        {
                            int peerId;
                            response.GetHandshakeTracker(out peerId);
                            PeerId = peerId;
                            IsConnected = true;
                            Logger.WriteLine("Connection to tracker is successfully established. PeerID: " + PeerId);

                            IPAddress ipAddr = (trackerSocket.LocalEndPoint as IPEndPoint).Address;
                            IPEndPoint ipEndPointListener = new IPEndPoint(ipAddr, Configuration.ListenPort);
                            SocketPermission permissionListener = new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", Configuration.ListenPort);

                            listenerSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                            listenerSocket.Bind(ipEndPointListener);

                            permission.Demand();

                            waitPeer = new Thread(new ParameterizedThreadStart(WaitPeer));
                            waitPeer.Start(4);

                            keepAlive = new Thread(new ThreadStart(SendAliveTracker));
                            keepAlive.Start();
                            return true;
                        }
                        else
                        {
                            Logger.WriteLine("Failed to connect to tracker.");
                            return false;
                        }
                    }
                    else
                    {
                        Logger.WriteLine("Failed to connect, tracker not found.");
                        return false;
                    }
                }
                else
                {
                    Logger.WriteLine("Already connected to tracker.");
                    return false;
                }
            }
            catch (SocketException exc)
            {
                Logger.WriteLine(exc);
                return false;
            }
        }
コード例 #8
0
ファイル: Tracker.cs プロジェクト: edwardsamuel/Gunbond
        public void ReceiveCallback(IAsyncResult target)
        {
            try
            {
                object[] obj = new object[2];
                obj = (object[])target.AsyncState;

                byte[] data = (byte[])obj[0];
                Socket handler = (Socket)obj[1];
                IPAddress tempIP = (handler.RemoteEndPoint as IPEndPoint).Address;

                string content = string.Empty;
                int bytesRead = handler.EndReceive(target);

                if (bytesRead > 0)
                {
                    Message request = new Message(data);
                    Message response;

                    Message.MessageType requestType = request.GetMessageType();
                    if (requestType == Message.MessageType.HandshakePeer)
                    {
                        #region Handshake
                        Logger.WriteLine("New peer with IP Address " + (handler.RemoteEndPoint as IPEndPoint).Address.ToString() + " request handshake.");

                        if (peers.Count < Configuration.MaxPeer)
                        {
                            int newPeerId = GenerateNewPeerId();
                            Peer peer = new Peer(newPeerId, (handler.RemoteEndPoint as IPEndPoint).Address);
                            peers.Add(newPeerId, peer);

                            Logger.WriteLine("Peer with IP Address " + (handler.RemoteEndPoint as IPEndPoint).Address.ToString() + " registered with ID " + newPeerId + ".");
                            Logger.WriteLine(peer);
                            Logger.WriteLine();

                            // send handshake response with ID
                            response = Message.CreateMessageHandshakeTracker(newPeerId);
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send handshake response with ID
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.KeepAlive)
                    {
                        #region Keep Alive
                        int peerId;
                        Peer peer;
                        request.GetKeepAlive(out peerId);
                        if (peers.TryGetValue(peerId, out peer))
                        {
                            Logger.WriteLine("Keep alive is sent by Peer: " + peer);

                            // send KEEP ALIVE message back
                            response = request;
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send FAIL message that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.CreateRoom)
                    {
                        #region Create Room
                        int peerId, maxPlayers, listenPort;
                        string roomId;
                        request.GetCreate(out peerId, out maxPlayers, out roomId, out listenPort);

                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer))
                        {
                            Room room;
                            if (!rooms.TryGetValue(roomId, out room))
                            {
                                room = new Room(roomId, peer, maxPlayers, listenPort);
                                rooms.Add(roomId, room);
                                Logger.WriteLine("Create room request is sent by peer " + peer + " for room " + room);

                                // send reply message SUCCESS
                                response = Message.CreateMessageSuccess();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                            else
                            {
                                // send message FAIL that room doesn't exist
                                response = Message.CreateMessageFailed();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.ListRoom)
                    {
                        #region List Room
                        int peerId;
                        request.GetList(out peerId);

                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {
                            Logger.WriteLine("List room is sent to Peer " + peer);
                            List<Message.MessageRoomBody> listRooms = new List<Message.MessageRoomBody>();
                            foreach (var r in rooms.Values)
                            {
                                Message.MessageRoomBody mb;
                                mb.roomId = r.Id;
                                mb.maxPlayers = r.MaxPlayers;
                                mb.currentPlayer = r.Members.Count;
                                listRooms.Add(mb);
                            }

                            // send ROOM message
                            response = Message.CreateMessageRoom(listRooms);
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Join)
                    {
                        #region Join Room
                        int peerId;
                        string roomId;
                        request.GetJoin(out peerId, out roomId);
                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {
                            Room room;
                            if (rooms.TryGetValue(roomId, out room) && room.Members.Count < room.MaxPlayers)
                            {
                                Logger.WriteLine("Join room request is sent by Peer " + peer + " for Room " + room);

                                // send IP address back to peer
                                response = Message.CreateMessageCreatorInfo(room.Creator.IpAddress, room.ListenPort);
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                            else
                            {
                                // send message FAIL that peer is not registered
                                response = Message.CreateMessageFailed();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Start)
                    {
                        #region Start
                        int peerId;
                        request.GetList(out peerId);
                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {

                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Quit)
                    {
                        #region Quit
                        int peerId;
                        request.GetList(out peerId);
                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {

                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion

                        //}
                        //else if (requestType == Message.MessageType.Add)
                        //{
                        //    #region Add
                        //    int peerId;
                        //    request.GetList(out peerId);
                        //    Peer peer;
                        //    if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        //    {
                        //        // ...
                        //    }
                        //    else
                        //    {
                        //        // send message FAIL that peer is not registered
                        //        response = Message.CreateMessageFailed();
                        //        handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        //    }
                        //    #endregion
                    }
                    else if (requestType == Message.MessageType.Add)
                    {
                        #region Add
                        int peerId;
                        string roomId;
                        request.GetAdd(out peerId, out roomId);
                        Peer peer;
                        Room room;
                        if (peers.TryGetValue(peerId, out peer) && (rooms.TryGetValue(roomId, out room)))
                        {
                            room.AddPeer(peer);
                            response = Message.CreateMessageSuccess();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Remove)
                    {
                        #region Remove
                        int peerId;
                        int creatorId;
                        int creatorPort;
                        string roomId;

                        request.GetRemove(out peerId, out creatorId, out creatorPort, out roomId);
                        Room room;
                        if (rooms.TryGetValue(roomId, out room))
                        {
                            room.RemovePeer(peerId);
                            Peer creator;
                            room.Members.TryGetValue(creatorId, out creator);
                            room.Creator = creator;
                            room.ListenPort = creatorPort;

                            response = Message.CreateMessageSuccess();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else
                    {
                        Logger.WriteLine("Unknown message received from " + (handler.RemoteEndPoint as IPEndPoint));
                        // throw message failed
                        response = Message.CreateMessageFailed();
                        handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                    }

                    #region Receive for Next Message
                    byte[] buffer = new byte[1024];
                    obj = new object[2];
                    obj[0] = buffer;
                    obj[1] = handler;
                    IAsyncResult nextAsyncResult = handler.BeginReceive(
                        buffer,
                        0,
                        buffer.Length,
                        SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        obj
                        );

                    if (!nextAsyncResult.AsyncWaitHandle.WaitOne(Configuration.MaxTimeout))
                    {
                        Logger.WriteLine("Connection timeout for peer with IP Address " + (handler.LocalEndPoint as IPEndPoint).Address + ":" + (handler.LocalEndPoint as IPEndPoint).Port + " -> " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);

                        // find peer id
                        int peerId = 0;
                        foreach (KeyValuePair<int, Peer> entry in peers)
                        {
                            if (entry.Value.IpAddress.Equals((handler.RemoteEndPoint as IPEndPoint).Address))
                            {
                                peerId = entry.Key;
                                break;
                            }
                        }
                        peers.Remove(peerId);

                        handler.Close();
                    }
                    #endregion
                }
            }
            catch (SocketException exc)
            {
                Logger.WriteLine(exc);
            }
        }
コード例 #9
0
ファイル: GunConsole.cs プロジェクト: edwardsamuel/Gunbond
        private void SendAliveTracker()
        {
            try
            {
                while (true)
                {
                    Logger.WriteLine("SendAliveTracker");
                    Message mes = Message.CreateMessageKeepAlive(PeerId);
                    byte[] buffer = new byte[1024];

                    lock (trackerPaddle)
                    {
                        trackerSocket.Send(mes.data, 0, mes.data.Length, SocketFlags.None);
                        trackerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    if (response.GetMessageType() == Message.MessageType.KeepAlive)
                    {
                        Logger.WriteLine("KeepAlive success.");
                        Thread.Sleep(Configuration.MaxTimeout / 10);
                    }
                    else
                    {
                        Logger.WriteLine("Message KeepAlive has not been received.");
                    }
                    Logger.WriteLine();
                }
            }
            catch (Exception)
            {
                lock (trackerPaddle)
                {
                    if (trackerSocket == null)
                    {
                        Logger.WriteLine("Connection terminated");
                        IsConnected = false;
                    }
                }
            }
        }