P
P
Peter2018-03-02 14:42:22
C++ / C#
Peter, 2018-03-02 14:42:22

Why hangs the GUI of the server application?

Good afternoon.
Faced the problem of freezing the GUI in my server application.
There is such a server class:

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()}] отключился");
        }
    }
}

Called on the form like this:
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);
        } 
    }

The first problem is that the form only appears when the client connects. The second problem is that there is no multithreading. If the second, third and further client connects, they just hang.
There are no such problems in the console version. Where could I have made a mistake?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
tex0, 2018-03-02
@Morpheus_God

Your server is running in synchronous mode.
When you call listenSocket.Accept() , that call will block the current thread until the server socket has responded to a client connection.
Use asynchronous operations a la TPL , well, or you can do it the old fashioned way Begin-End

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question