コード例 #1
0
        /// <summary>
        /// Take the incoming data from a client and convert it into a TFMS_Data object
        /// </summary>
        /// <param name="socket">the socket that connects the server and the client</param>
        /// <param name="info">the information about the client from the socket</param>
        /// <param name="result">the result of the connection attempt</param>
        /// <returns></returns>
        private TFMS_Data extractData(Socket socket, TFMS_ClientInfo info, IAsyncResult result)
        {
            try
            {
                int numBytesReceived = socket.EndReceive(result); // EndReceive returns how many bytes were received
                byte[] temp = new byte[numBytesReceived];

                // the buffer might not be used for the first Received message so check if it exists
                // otherwise use the default buffer
                if (info == null || info.buffer == null)
                    Array.Copy(byteData, temp, numBytesReceived);
                else
                    Array.Copy(info.buffer, temp, numBytesReceived);

                // parse the bytes and turn it into a TFMS_Data object
                return new TFMS_Data(temp);
            }
            catch (SocketException)
            {
                // if something goes wrong, logoff the client
                return new TFMS_Data(TFMS_Command.Logout, null, getNamefromSocket(socket));
            }
        }
コード例 #2
0
        /// <summary>
        /// this hadles the actual message forwarding ect.
        /// you should never call this function directly
        /// </summary>
        /// <param name="result">this encapsulates the Socket of the client</param>
        public void OnReceive(IAsyncResult result)
        {
            // get the socket that received data
            Socket clientSocket = (Socket)result.AsyncState;

            // get the ClientInfo from the connected client
            TFMS_ClientInfo CI = null;
            if (findIndexFromClient(clientList, clientSocket) >= 0)
                CI = clientList[findIndexFromClient(clientList, clientSocket)];

            Console.WriteLine("\n****************************************");
            Console.WriteLine("Data Received from {0}", getNamefromSocket(clientSocket));

            // attempt to get the data from the client and convert it into TFMS_Data object
            TFMS_Data msgReceived = extractData(clientSocket, CI, result);

            TFMS_Data msgToSend = new TFMS_Data();
            msgToSend.cmdCommand = msgReceived.cmdCommand;
            msgToSend.strName = msgReceived.strName;

            #region Interpret incoming message command

            // set the message to send, client info buffer size, and client info based on the incoming command
            switch (msgReceived.cmdCommand)
            {
                case TFMS_Command.Login:    // new client logging in
                    #region Login command

                    Console.WriteLine("Received login from {0}", getNamefromSocket(clientSocket));

                    // tell the server a logon was requested
                    logonRequested(msgReceived);

                    // add the new client to the current list of clients
                    TFMS_ClientInfo clientInfo = new TFMS_ClientInfo(clientSocket, msgReceived.strName);
                    clientList.Add(clientInfo);

                    // pass the incoming client's name to other clients
                    msgToSend.strMessage = msgReceived.strName;
                    clientInfo.buffer = new byte[TFMS_Constants.BUFFER_SIZE]; // dimension the clients buffer.
                    CI = clientInfo; // CI would not have been found before since its not in the clientList so just add it now

                    #endregion
                    break;
                case TFMS_Command.Logout:   // client logging out
                    #region Logout command

                    Console.WriteLine("Received Logout from {0}", getNamefromSocket(clientSocket));

                    // tell the server a logout was requested
                    logoffRequested(msgReceived);

                    // remove the client from the list of connected clients.
                    clientList.RemoveAt(findIndexFromClient(clientList, clientSocket));
                    clientSocket.Close();

                    // pass the client's name to other clients
                    msgToSend.strMessage = msgReceived.strName;

                    #endregion
                    break;
                case TFMS_Command.List:     // client requesting a list of all clients
                    #region List command

                    Console.WriteLine("Received List request from {0}", getNamefromSocket(clientSocket));

                    // tell the server a list of clients was requested
                    listRequested(msgReceived);

                    // get the list of all currently connected clients
                    msgToSend = GetClientListMessage();

                    // send the message to a single client
                    sendTFMSmsg(msgToSend, clientSocket, new AsyncCallback(OnSend));

                    #endregion
                    break;
                case TFMS_Command.Message:  // incoming message to be broadcast
                    #region Message command

                    Console.WriteLine("Received TFM from {0} (size={1})", getNamefromSocket(clientSocket), CI.buffer.Length);

                    // tell the server a message broadcast was requested
                    relayRequested(msgReceived);

                    // copy the message to the server's outgoing message field
                    msgToSend.strMessage = msgReceived.strMessage;

                    #endregion
                    break;
                case TFMS_Command.MsgLen:   // incoming message is greater than the current buffer size
                    #region Long Message command

                    Console.WriteLine("Received long TFM from {0} (size={1})", getNamefromSocket(clientSocket), CI.buffer.Length);

                    // resize the buffer for the incoming large message
                    CI.buffer = new byte[int.Parse(msgReceived.strMessage) + TFMS_Constants.BUFFER_SIZE];

                    #endregion
                    break;
                default:                    // unrecognizable command
                    #region Unknown command

                    // we gracefully fail and gtfoh
                    Console.WriteLine("Cant interpret command! Aborting this relay.");
                    Console.WriteLine("BeginReceive from {0}", getNamefromSocket(clientSocket));

                    // restart the receive command
                    clientSocket.BeginReceive(CI.buffer, 0, CI.buffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);

                    return;
                    #endregion
            }
            #endregion

            // send the message to every client logged in to the server
            broadcastToClients(msgToSend, clientList);

            // after a message is broadcast, begin listening for more incoming messages
            // NOTE: if many users are logged in at once, the broadcast method could block other incoming messages
            // for future iterations of TFMS, we want the receiving command to run on a separate thread from the sending command
            if (msgReceived.cmdCommand != TFMS_Command.Logout)
            {
                Console.WriteLine("Waiting for data from {0}", getNamefromSocket(clientSocket));
                clientSocket.BeginReceive(CI.buffer, 0, CI.buffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
            }
        }