Morpheus_God
@Morpheus_God

Почему зависает GUI у приложения сервера?

Добрый день.
Столкнулся с проблемой зависания GUI в своем приложении сервер.
Есть вот такой класс сервера:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ServerGUI
{
    public delegate void GetMessage(string message);

    public class Server
    {
        private Socket listenSocket;
        private IPEndPoint ip;


        public event GetMessage ServerStatus;


        public Server(int port)
        {
            listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ip = new IPEndPoint(IPAddress.Any, port);
        }

        public void StartServer(int backlog)
        {
            listenSocket.Bind(ip);
            listenSocket.Listen(backlog);
            ServerStatus?.Invoke($"[{DateTime.Now.ToString()}] Сервер запущен. Ожидаю подключения..");
        }


        public void ClientAccept()
        {
            Socket clientSocket = listenSocket.Accept();
            ServerStatus?.Invoke($"[{DateTime.Now.ToString()}] [{((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString()}] подключился");

            Thread cl = new Thread(() => MessageDecode(clientSocket));
            cl.Start();
        }


        private void MessageDecode(Socket clientSocket)
        {
            byte[] buffer = new byte[clientSocket.SendBufferSize];
            int readByte;
            do
            {
                readByte = clientSocket.Receive(buffer);
                byte[] rData = new byte[readByte];
                Array.Copy(buffer, rData, readByte);
                string data = Encoding.Unicode.GetString(rData);


                ServerStatus?.Invoke($"[{DateTime.Now.ToString()}] [{((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString()}] написал: " + data);
                clientSocket.Send(new byte[3] { 89, 69, 83 });
               
            } while (readByte > 0);

            ServerStatus?.Invoke($"[{DateTime.Now.ToString()}] [{((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString()}] отключился");
        }
    }
}

На форме вызывается вот так:
public partial class ServerForm : Form
    {
        Server server = new Server(904);

        public ServerForm()
        {
            InitializeComponent();
            server.StartServer(5);
            server.ClientAccept();
            server.ServerStatus += Server_ServerStatus;
        }

        private void Server_ServerStatus(string message)
        {
            MethodInvoker invoker = new MethodInvoker(delegate
            {
                tblog.Text += $"\r\n {message}";
            });

            this.Invoke(invoker);
        } 
    }

Первая проблема, это то, что форма появляется только при подключении клиента. Вторая проблема в том, что нет мультипоточности. Если подключается второй,третий и далее клиент они просто висят.
В консольном исполнении таких проблем нет. Где я мог допустить ошибку?
  • Вопрос задан
  • 104 просмотра
Решения вопроса 1
@tex0
У вас сервер работает в синхронном режиме.
Когда вы вызываете listenSocket.Accept() этот вызов блокирует текущий поток до тех пор, пока серверный сокет не среагирует на подключение клиента.
Используйте асинхронные операции аля TPL ну или можно по старинке Begin-End
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы