我创建了服务器和客户端一切正常,直到我做了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);
}
}
}
答案 0 :(得分:0)
首先(为了将来的使用),您更善于使用TcpClient
和TcpListener
类,而是让事情变得更容易。
其次,我认为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
,除了您断开连接的区域中的那个,因为其他方法都没用。一旦if
或else if
块成功执行,其他块将被忽略 - 这意味着您不必终止该方法。
删除退货将使您的
socket.BeginReceive(_buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
行总是执行,这意味着服务器将继续读取命令,直到连接终止。