我可以从另一个类调用Form1的组件 [英] TCP / Server I can from another class call the components of Form1

查看:0
本文介绍了我可以从另一个类调用Form1的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将此示例作为服务器。 这个问题只适用于我在游戏机上。 我想将其传递到Windows窗体。我不知道如何使用它。

因为我知道这是另一个类的不良做法,例如在Server类中创建Form1方法和使用Form1对象。

好像在服务器类中我调用了TextBox或类似的东西。

我认为我必须将所有代码改回Windows窗体的问题?

或者停止使用类,并使用典型的TcpClient、TpcListener,就像在Form1中声明它的视频中那样。

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Chatroom
{

    delegate void MessageEventHandler(object sender, MessageEventArgs e);

    class MessageEventArgs : EventArgs
    {
        public string Message { get; private set; }

        public MessageEventArgs(string message)
        {
            this.Message = message;
        }
    }

    class Server
    {
        private TcpListener serverSocket;
        private List<Worker> workers = new List<Worker>();

        public Server(int port)
        {
            //serverSocket = new TcpListener(port);// deprecated
            // the same way
            serverSocket = new TcpListener(IPAddress.Any, port);
            serverSocket.Start();
        }

        private void WaitForConnection()
        {
            while (true)
            {
                TcpClient socket = serverSocket.AcceptTcpClient();
                Worker worker = new Worker(socket);
                AddWorker(worker);
                worker.Start();
            }
        }

        private void Worker_MessageReceived(object sender, MessageEventArgs e)
        {
            BroadcastMessage(sender as Worker, e.Message);
        }

        private void Worker_Disconnected(object sender, EventArgs e)
        {
            RemoveWorker(sender as Worker);
        }

        private void AddWorker(Worker worker)
        {
            lock (this)
            {
                workers.Add(worker);
                worker.Disconnected += Worker_Disconnected;
                worker.MessageReceived += Worker_MessageReceived;
            }
        }

        private void RemoveWorker(Worker worker)
        {
            lock (this)
            {
                worker.Disconnected -= Worker_Disconnected;
                worker.MessageReceived -= Worker_MessageReceived;
                workers.Remove(worker);
                worker.Close();
            }
        }

        private void BroadcastMessage(Worker from, String message)
        {
            lock (this)
            {
                message = string.Format("{0}: {1}", from.Username, message);
                for (int i = 0; i < workers.Count; i++)
                {
                    Worker worker = workers[i];
                    if (!worker.Equals(from))
                    {
                        try
                        {
                            worker.Send(message);
                        }
                        catch (Exception)
                        {
                            workers.RemoveAt(i--);
                            worker.Close();
                        }
                    }
                }
            }
        }

        class Worker
        {
            public event MessageEventHandler MessageReceived;
            public event EventHandler Disconnected;
            private readonly TcpClient socket;
            private readonly Stream stream;
            public string Username { get; private set; } = null;

            public Worker(TcpClient socket)
            {
                this.socket = socket;
                this.stream = socket.GetStream();
            }

            public void Send(string message)
            {
                byte[] buffer = Encoding.UTF8.GetBytes(message);
                stream.Write(buffer, 0, buffer.Length);
            }

            public void Start()
            {
                new Thread(Run).Start();
            }

            private void Run()
            {
                byte[] buffer = new byte[2018];
                try
                {
                    while (true)
                    {
                        int receivedBytes = stream.Read(buffer, 0, buffer.Length);
                        if (receivedBytes < 1)
                            break;
                        string message = Encoding.UTF8.GetString(buffer, 0, receivedBytes);
                        if (Username == null)
                            Username = message;
                        else
                            MessageReceived?.Invoke(this, new MessageEventArgs(message));
                    }
                }
                catch (IOException) { }
                catch (ObjectDisposedException) { }
                Disconnected?.Invoke(this, EventArgs.Empty);
            }

            public void Close()
            {
                socket.Close();
            }
        }

        static void Main(string[] args)
        {
            try
            {
                Server server = new Server(3393);
                server.WaitForConnection();
            }
            catch (IOException) { }
        }
    }
}

问题在于。如果我有Form1。

正如我所描述的,正如我所做的那样。每次创建新客户端时,都会通过来自Server类的列表框添加该客户端。理论上你不能,或者你能不能,或者这是不好的做法?

Class Server{
private void RemoveWorker(Worker worker)
        {
            lock (this)
            {
                **textbox.text +="Cliente desconectado";**
                worker.Disconnected -= Worker_Disconnected;
                worker.MessageReceived -= Worker_MessageReceived;
                workers.Remove(worker);
                worker.Close();
            }
        }
}

如果不在WindForm主类中,如何完成此操作

推荐答案

以下是帮助您入门的步骤。

  1. 在VisualStudio中新建WinForms项目。
  2. 您的项目应立即生成并显示窗体,而无需执行任何操作。
  3. 您应该有包含Main()方法的Program.cs。您不需要更改它。这就是加载和显示Form1的原因。
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
  1. 您可以右键单击Form1.cs,然后选择View Code以查看代码隐藏页面。
  2. 在那里,您将拥有具有InitializeComponent()方法的构造函数,该方法可以创建您的所有图形用户界面。
  3. 添加要在加载表单时运行的侦听程序。这是您可以添加服务器内容的地方。
  4. 打开您的图形用户界面设计器,转到-Properties并将一个新函数添加到
  5. 这是您要编写代码的地方。例如,您可以创建并启动服务器。
private void Form1_Load(object sender, EventArgs e)
{
    try
    {
        Server server = new Server(3393);
        server.WaitForConnection();
    }
    catch (IOException) { // Put something here like a log }
}
  1. 您的服务器可以转到一个新类,该类可以位于Server.cs这样的新文件中。只需确保WaitForConnection()public

这应该可以让您开始使用。遇到问题时,只需在SO上创建新问题,并确保添加最新代码。

建议:

  • 使用delegate在服务器和图形用户界面之间进行通信
  • 您可能希望在另一个线程中运行服务器。首先测试它以使其正常工作,看看这是否是您需要的/想要的
  • 您通常不希望将服务器作为WinForms项目运行。如果您不小心关闭该表单,则会终止您的服务器。
  • 确保有Form1_Close事件并正确关闭那里的服务器

这篇关于我可以从另一个类调用Form1的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆