Tcp 客户端发送命令到 Tcp 服务器启动 x.exe 之后服务器忽略客户端
Tcp client send command toTcp Server to start x.exe and later server ignores client
我已经创建了服务器和客户端,一切正常,直到我做了 1 处更改。创建的命令开始 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);
}
}
}
首先(为了将来使用),您最好使用 TcpClient
和 TcpListener
类,它们使事情变得容易得多。
其次,我认为 flag
布尔值没有任何意义。这完全没用。如果你需要检查一些东西,就做 if(Textmessage.ToLower() == "x.exe")
因为它已经 returns a bool
.
第三也是最后,您的服务器停止接收是因为您没有让它在处理命令后再次开始等待数据。在你处理完一个有效的命令后,你调用 return;
这将阻止你的代码调用 socket.BeginReceive()
方法。
else if(flag = Textmessage.ToLower() == "x.exe") //command from client
{
...code...
return; //<-- Your problem.
}
您应该删除 ReceiveCallback
方法中的每个 return;
, 除了您断开连接的块中的那个 ,因为其他没用。一旦 if
或 else if
块成功执行,其他块将被忽略 - 这意味着您不必终止该方法。
删除 returns 将使您的
socket.BeginReceive(_buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
行始终执行,这意味着服务器将继续读取命令,直到连接终止。
我已经创建了服务器和客户端,一切正常,直到我做了 1 处更改。创建的命令开始 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);
}
}
}
首先(为了将来使用),您最好使用 TcpClient
和 TcpListener
类,它们使事情变得容易得多。
其次,我认为 flag
布尔值没有任何意义。这完全没用。如果你需要检查一些东西,就做 if(Textmessage.ToLower() == "x.exe")
因为它已经 returns a bool
.
第三也是最后,您的服务器停止接收是因为您没有让它在处理命令后再次开始等待数据。在你处理完一个有效的命令后,你调用 return;
这将阻止你的代码调用 socket.BeginReceive()
方法。
else if(flag = Textmessage.ToLower() == "x.exe") //command from client
{
...code...
return; //<-- Your problem.
}
您应该删除 ReceiveCallback
方法中的每个 return;
, 除了您断开连接的块中的那个 ,因为其他没用。一旦 if
或 else if
块成功执行,其他块将被忽略 - 这意味着您不必终止该方法。
删除 returns 将使您的
socket.BeginReceive(_buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
行始终执行,这意味着服务器将继续读取命令,直到连接终止。