Tcp客户端发送命令toTcp Server启动x.exe,后来服务器忽略客户端

时间:2016-03-12 11:29:41

标签: c# tcpclient tcpserver

我创建了服务器和客户端一切正常,直到我做了1次更改。创建命令start x.exe。

 if(flag = Textmessage.ToLower() == "x.exe") //command from client
         {          
            ProcessStartInfo _processStartInfo = new ProcessStartInfo();
            _processStartInfo.WorkingDirectory = @"C:\Users\audrius\OneDrive\Programavimas\x\Bin\Debug\";
            _processStartInfo.FileName = @"x.exe";
            Process myProcess = Process.Start(_processStartInfo);

            byte[] bytes = Encoding.ASCII.GetBytes("exe started");
            socket.Send(bytes);//TELL client program started
            ServerLogs.ServerLog("exe started");
            Console.WriteLine("exe started");
            return;
        }

一切正常,我从服务器得到程序启动的响应。但是我想发送下一个命令服务器不接受它。只有这样我才重新启动客户端,服务器接受命令。为什么服务器与此客户端冻结? 我的客户代码:

 namespace Multi_Client
{
class Program
{
    private static readonly Socket _clientSocket = new Socket
        (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    private const int _PORT = 100;
    static string name = "Client";
    static void Main()
    {
        Console.WriteLine("Welcome {0}", name); 
        Console.Title = "Client";
        ConnectToServer();
        RequestLoop();
        Exit();
    }

    private static void ConnectToServer()
    {
        int attempts = 0;

        while (!_clientSocket.Connected)
        {
            try
            {
                attempts++;
                Console.WriteLine("Connection attempt " + attempts);
                _clientSocket.Connect(IPAddress.Loopback, _PORT);
            }
            catch (SocketException) 
            {
                Console.SetCursorPosition(0, Console.CursorTop - 1);
                Console.Write(new string(' ', Console.WindowWidth));
                Console.SetCursorPosition(0, Console.CursorTop - 1);
            }
        }

       // Console.Clear();
        Console.WriteLine("Connected");
    }

    private static void RequestLoop()
    {
        Console.WriteLine(@"<Type ""exit"" to properly disconnect client>");

        while (true)
        {
            SendRequest();
            ReceiveResponse();
        }
    }

    /// <summary>
    /// Close socket and exit app
    /// </summary>
    private static void Exit()
    {
        SendString(name+ "exit"); // Tell the server we re exiting
        _clientSocket.Shutdown(SocketShutdown.Both);
        _clientSocket.Close();
        System.Threading.Thread.Sleep(1000);
        Environment.Exit(0);
    }

    private static void SendRequest()
    {
        Console.Write("Send a request: ");
        string request = name + " "+ Console.ReadLine();
        SendString(request);
        System.Threading.Thread.Sleep(1000);          

        if (request.ToLower() == name +" exit")
        {
            Exit();
        }
    }
    /// <summary>
    /// Sends a string to the server with ASCII encoding
    /// </summary>
    private static void SendString(string text)
    {
        byte[] buffer = Encoding.ASCII.GetBytes(text);
       _clientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);                     
    }

    private static void ReceiveResponse()
    {
        if (_clientSocket.Connected)
        {
            var buffer = new byte[2048];
            int received = _clientSocket.Receive(buffer, SocketFlags.None);
            if (received == 0) return;
            var data = new byte[received];
            Array.Copy(buffer, data, received);
            string text = Encoding.ASCII.GetString(data);
            Console.WriteLine(text);
        }
    }
}

} 我的服务器:

     namespace Multi_Server
 {
   internal class Program
    {
    private static Socket _serverSocket;
    private static readonly List<Socket> _clientSockets = new List<Socket>      ();
    private const int _BUFFER_SIZE = 2048;
    private const int _PORT = 100;
    private static readonly byte[] _buffer = new byte[1024];

    private static void Main()
    {
        Console.Title = "Server";
        Program.SetupServer();
        Console.ReadLine();
        Program.CloseAllSockets();
    }

    private static void SetupServer()
    {
        ServerLogs.ServerLog("Setting up server...");
        Console.WriteLine("Setting up server...");
        Program._serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Program._serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
        Program._serverSocket.Listen(5);
        Program._serverSocket.BeginAccept(new AsyncCallback(Program.AcceptCallback), null);
        Console.WriteLine("Server setup complete");
        ServerLogs.ServerLog("Server setup complete");
    }

    private static void CloseAllSockets()
    {
        foreach (Socket socket in _clientSockets)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }

        _serverSocket.Close();
    }

    private static void AcceptCallback(IAsyncResult AR)
    {
        Socket socket;
        try
        {
            socket = _serverSocket.EndAccept(AR);
        }
        catch (ObjectDisposedException)
        {
            return;
        }
        Program._clientSockets.Add(socket);
        socket.BeginReceive(Program._buffer, 0, 1024, SocketFlags.None, new AsyncCallback(Program.ReceiveCallback), socket);
        Console.WriteLine("Client connected, waiting for request...");
        ServerLogs.ServerLog("Client connected, waiting for request...");
        _serverSocket.BeginAccept(AcceptCallback, null);
    }

    private static void ReceiveCallback(IAsyncResult AR)
    {
        Socket socket = (Socket)AR.AsyncState;
        int num;
        try
        {
            num = socket.EndReceive(AR);
        }
        catch (SocketException)
        {
            Console.WriteLine("Client forcefully disconnected");
            ServerLogs.ServerLog("Client forcefully disconnected");
            socket.Close();
            _clientSockets.Remove(socket);
            return;
        }
        byte[] array = new byte[num];
        Array.Copy(_buffer, array, num);
        string RawText = Encoding.ASCII.GetString(array);
        char[] textarray = RawText.ToCharArray();
        int i = 0;
        string name = "";

        while (textarray[i] != ' ')
        {
            name += textarray[i];
            i++;
        }
        string Textmessage = RawText.Substring(++i);

        ServerLogs.ServerLog("Received from " + name + " !> Text: " + Textmessage);
        Console.WriteLine("Received from {0} !> Text: {1}", name, Textmessage);

        bool flag;
        if(flag = Textmessage.ToLower() == "get time")
        {
            Console.WriteLine("Text is a get time request");
            ServerLogs.ServerLog("Text is a get time request");
            byte[] bytes = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
            socket.Send(bytes);
            ServerLogs.ServerLog("Time sent to client");
            Console.WriteLine("Time sent to client");
        }              
        else if(flag = Textmessage.ToLower() == "exit")
        {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                _clientSockets.Remove(socket);
                ServerLogs.ServerLog("Client disconnected");
                Console.WriteLine("Client disconnected");
            return;
        }               
        else if(flag = Textmessage.ToLower() == "x.exe") //command from client
         {             

            ProcessStartInfo _processStartInfo = new ProcessStartInfo();
            _processStartInfo.WorkingDirectory = @"C:\Users\audrius\OneDrive\Programavimas C#\Steambot Scrapper\Bin\Debug\";
            _processStartInfo.FileName = @"x.exe";
            Process myProcess = Process.Start(_processStartInfo);

            byte[] bytes = Encoding.ASCII.GetBytes("exe started");
            socket.Send(bytes);
            ServerLogs.ServerLog("exe started");
            Console.WriteLine("exe started");
            return;
        }
        else 
         { 
            ServerLogs.ServerLog("Text is an invalid request");
            Console.WriteLine("Text is an invalid request");
            byte[] bytes = Encoding.ASCII.GetBytes("Invalid request");
            socket.Send(bytes);
            ServerLogs.ServerLog("Warning Sent");
            Console.WriteLine("Warning Sent");
         }
        socket.BeginReceive(_buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
    }
}
  }//ServerLogs.cs >>>
   class ServerLogs
   {
    private static string m_exePath = string.Empty;
    public  ServerLogs(string logMessage)
    {
        ServerLog(logMessage);
    }

    public static void ServerLog(string logMessage)
    {
        m_exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        try
        {
            using (StreamWriter w = File.AppendText(m_exePath + "\\" + "log.txt"))
            {
                Log(logMessage, w);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: "+ex);
        }
    }

    public static void Log(string logMessage, TextWriter txtWriter)
    {
        try
        {
            txtWriter.Write("\nLog Entry: ");
            txtWriter.WriteLine("{0} {1} : {2}", 
                DateTime.Now.DayOfWeek, DateTime.Now.ToLongTimeString(), logMessage);
          //  txtWriter.WriteLine("  :");
         //   txtWriter.Write(" :{0}", logMessage);
          //  txtWriter.WriteLine("-------------------------------");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex);
        }
    }


}

1 个答案:

答案 0 :(得分:0)

首先(为了将来的使用),您更善于使用TcpClientTcpListener类,而是让事情变得更容易。

其次,我认为flag布尔值没有意义。这完全没用。如果您需要检查某些内容,请执行if(Textmessage.ToLower() == "x.exe"),因为它已经返回bool

第三,最后,您的服务器停止接收,因为您在处理完命令后不会再次开始等待数据。在您处理完有效命令后,请致电return;,这将阻止您的代码调用socket.BeginReceive()方法。

else if(flag = Textmessage.ToLower() == "x.exe") //command from client
{          
   ...code...
   return; //<-- Your problem.
}

您应该删除return;方法中的每个ReceiveCallback除了您断开连接的区域中的那个,因为其他方法都没用。一旦ifelse if块成功执行,其他块将被忽略 - 这意味着您不必终止该方法。

删除退货将使您的

socket.BeginReceive(_buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);

行总是执行,这意味着服务器将继续读取命令,直到连接终止。