How would I constant listen on a port with a GUI?

纵饮孤独 提交于 2020-12-03 23:47:33

问题


I am trying to learn TCP server/client interaction. I want to know how I would listen to a port all the time with GUI. Currently I am using this code:

    private void Form1_Load(object sender, EventArgs e)
    {
        CreateServer();
    }

    void CreateServer()
    {
        TcpListener tcp = new TcpListener(25565);
        tcp.Start();

        Thread t = new Thread(() =>
        {

            while (true)
            {
                var tcpClient = tcp.AcceptTcpClient();

                ThreadPool.QueueUserWorkItem((_) =>
                {
                    Socket s = tcp.AcceptSocket();
                    
                    console.Invoke((MethodInvoker)delegate { console.Text += "Connection esatblished: " + s.RemoteEndPoint + Environment.NewLine; });

                    byte[] b = new byte[100];
                    int k = s.Receive(b);


                    for (int i = 0; i < k; i++)
                    {
                        console.Text += Convert.ToChar(b[i]);
                        incoming += Convert.ToChar(b[i]);
                    }

                    MessageBox.Show(incoming);

                    console.Invoke((MethodInvoker)delegate { console.Text += incoming + Environment.NewLine; });

                    list.Invoke((MethodInvoker)delegate { list.Items.Add(incoming); });

                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes("\n"));

                    tcpClient.Close();
                }, null);
            }
        });
        t.IsBackground = true;
        t.Start();
    }

Any help would be much appreciateed.


回答1:


Short answer - run TCP listener in the separate Thread/Task (TPL). For full working solution you also have to implement dispatching of the any changes to UI form separate thread to main thread using special technique which is depends on Framework you are using, I mean WPF/WinForms/whatever.

Code below works for me fine. Read TODO section before.

TODO:

  • Add to form Textbox, ListBox, Button, make public:

    public System.Windows.Forms.TextBox console;
    public System.Windows.Forms.ListBox incommingMessages;
    private System.Windows.Forms.Button sendSampleDataButton;
    

Entry point:

private static Form1 form;

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    form = new Form1();
    form.Load += OnFormLoad;
    Application.Run(form);
}

private static void OnFormLoad(object sender, EventArgs e)
{
    CreateServer();
}

Server:

private static void CreateServer()
{
    var tcp = new TcpListener(IPAddress.Any, 25565);
    tcp.Start();

    var listeningThread = new Thread(() =>
    {
        while (true)
        {
            var tcpClient = tcp.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem(param =>                                                            
            {                        
                NetworkStream stream = tcpClient.GetStream();
                string incomming;                        
                byte[] bytes = new byte[1024];
                int i = stream.Read(bytes, 0, bytes.Length);                                                
                incomming = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                form.console.Invoke(
                (MethodInvoker)delegate
                    {
                        form.console.Text += String.Format(
                            "{0} Connection esatblished: {1}{2}", 
                            DateTime.Now,
                            tcpClient.Client.RemoteEndPoint,
                            Environment.NewLine);
                    });

                MessageBox.Show(String.Format("Received: {0}", incomming));
                form.incommingMessages.Invoke((MethodInvoker)(() => form.incommingMessages.Items.Add(incomming)));
                tcpClient.Close();
            }, null);
        }
    });

    listeningThread.IsBackground = true;
    listeningThread.Start();
}

Client

private void button1_Click(object sender, EventArgs e)
{
    Connect("localhost", "hello localhost " + Guid.NewGuid());
}

static void Connect(String server, String message)
{
    try
    {               
        Int32 port = 25565;
        TcpClient client = new TcpClient(server, port);             
        Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
        NetworkStream stream = client.GetStream();

        // Send the message to the connected TcpServer. 
        stream.Write(data, 0, data.Length);                                
        stream.Close();
        client.Close();
    }
    catch (ArgumentNullException e)
    {
        Debug.WriteLine("ArgumentNullException: {0}", e);
    }
    catch (SocketException e)
    {
        Debug.WriteLine("SocketException: {0}", e);
    }          
}

Screenshot:

enter image description here




回答2:


Create a thread, start to listen in it & don't stop the server

void CreateServer()
{
    TcpListener tcp = new TcpListener(25565);
    tcp.Start();

    Thread t = new Thread(()=>
    {
        while (true)
        {
            var tcpClient = tcp.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem((_) =>
            {
                //Your server codes handling client's request.
                //Don't access UI control directly here
                //Use "Invoke" instead. 
                tcpClient.Close();
            },null);
        }
    });
    t.IsBackground = true;
    t.Start();
}



回答3:


You could use the threads approach (as mentioned by other answers) or use asynchronous sockets, which in my opnion is way better. And even better, you can use the async model proposed by SocketAsyncEventArgs. Async sockets will take benefits from using completion ports.




回答4:


here is a good example on mdsn: Asynchronous server socket example



来源:https://stackoverflow.com/questions/9533013/how-would-i-constant-listen-on-a-port-with-a-gui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!