WPF 服务器应用程序
本文关键字:应用程序 服务器 WPF | 更新日期: 2023-09-27 17:56:49
我有一个WPF服务器和客户端应用程序。当我启动服务器时,它开始侦听传入的消息。但是,无法触摸或关闭应用程序,它会"卡住"在侦听中。我必须补充一点,它在处理消息等方面做了它应该做的事情。但我就是无法与表单交互。它与异步服务器套接字有关吗?我不确定要寻找什么...
这是我的服务器代码:
private void startServer()
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sck.Bind(new IPEndPoint(0, serverPort));
sck.Listen(100);
while (true)
{
Socket accepted = sck.Accept();
Buffer = new byte[accepted.SendBufferSize];
int bytesRead = accepted.Receive(Buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = Buffer[i];
}
string command = Encoding.ASCII.GetString(formatted);
string[] splittedCommand = command.Split(' ');
jobsHistory.Items.Add(Encoding.ASCII.GetString(formatted));
jobsHistory.Refresh();
Process processToRun = new Process();
processToRun.StartInfo.FileName = splittedCommand[0];
processToRun.StartInfo.WorkingDirectory = Path.GetDirectoryName(splittedCommand[0]);
processToRun.StartInfo.Arguments = "";
for (int i = 1; i < splittedCommand.Length; i++)
{
processToRun.StartInfo.Arguments += " " + splittedCommand[i];
}
processToRun.Start();
accepted.Close();
}
}
如果这适用于 UI 线程,那么您正在将其捆绑在循环中。它没有机会处理任何 UI 事件。除此之外,Socket.Receive
还有一个阻止呼叫。
在这个网站和谷歌上都有许多关于BackgroundWorker类的文章。我建议你研究一下这些。
应使用 BeginAccept
在后台接受连接,而不会阻止 UI 线程。当客户端被接受时,再次调用BeginAccept
- 这将创建一个"循环"。然后,您可以删除while
循环。
startServer
方法可能如下所示:
private void startServer()
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sck.Bind(new IPEndPoint(0, serverPort));
sck.Listen(100);
sck.BeginAccept(Accepted, sck);
}
然后,在 Accepted
方法中,执行以下操作:
private void Accepted(IAsyncResult result)
{
Socket sck = result.AsyncState as Socket;
Socket client = sck.EndAccept(result);
sck.BeginAccept(Accepted, sck);
}
Socket accepted = sck.Accept();
只需在单独的线程中执行侦听,如下所示 -
private void startServer()
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sck.Bind(new IPEndPoint(0, 8080));
new Thread(() => StartListening(sck)).Start();
}
void StartListening(Socket socket)
{
socket.Listen(100);
Accept(socket);
}
void Accept(Socket socket)
{
while (true)
{
Socket accepted = socket.Accept();
Buffer = new byte[accepted.SendBufferSize];
int bytesRead = accepted.Receive(Buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = Buffer[i];
}
string command = Encoding.ASCII.GetString(formatted);
string[] splittedCommand = command.Split(' ');
jobsHistory.Items.Add(Encoding.ASCII.GetString(formatted));
jobsHistory.Refresh();
Process processToRun = new Process();
processToRun.StartInfo.FileName = splittedCommand[0];
processToRun.StartInfo.WorkingDirectory = Path.GetDirectoryName(splittedCommand[0]);
processToRun.StartInfo.Arguments = "";
for (int i = 1; i < splittedCommand.Length; i++)
{
processToRun.StartInfo.Arguments += " " + splittedCommand[i];
}
processToRun.Start();
accepted.Close();
}
// If you want to start listening again
socket.Close();
startServer();
}