TCP / Server I can from another class call the components of Form1(我可以从另一个类调用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主类中,如何完成此操作
推荐答案
以下是帮助您入门的步骤。
- 在VisualStudio中新建
WinForms
项目。 - 您的项目应立即生成并显示窗体,而无需执行任何操作。
- 您应该有包含
Main()
方法的Program.cs
。您不需要更改它。这就是加载和显示Form1
的原因。
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
- 您可以右键单击
Form1.cs
,然后选择View Code
以查看代码隐藏页面。 - 在那里,您将拥有具有
InitializeComponent()
方法的构造函数,该方法可以创建您的所有图形用户界面。 - 添加要在加载表单时运行的侦听程序。这是您可以添加服务器内容的地方。 打开您的图形用户界面设计器,转到-
- 这是您要编写代码的地方。例如,您可以创建并启动服务器。
Properties
并将一个新函数添加到
private void Form1_Load(object sender, EventArgs e)
{
try
{
Server server = new Server(3393);
server.WaitForConnection();
}
catch (IOException) { // Put something here like a log }
}
- 您的服务器可以转到一个新类,该类可以位于
Server.cs
这样的新文件中。只需确保WaitForConnection()
为public
。
这应该可以让您开始使用。遇到问题时,只需在SO上创建新问题,并确保添加最新代码。
建议:
- 使用
delegate
在服务器和图形用户界面之间进行通信 - 您可能希望在另一个线程中运行服务器。首先测试它以使其正常工作,看看这是否是您需要的/想要的
- 您通常不希望将服务器作为WinForms项目运行。如果您不小心关闭该表单,则会终止您的服务器。
- 确保有
Form1_Close
事件并正确关闭那里的服务器
这篇关于我可以从另一个类调用Form1的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:我可以从另一个类调用Form1的组件


- 为什么 C# 中的堆栈大小正好是 1 MB? 2022-01-01
- 带问号的 nvarchar 列结果 2022-01-01
- 在 LINQ to SQL 中使用 contains() 2022-01-01
- C# 通过连接字符串检索正确的 DbConnection 对象 2022-01-01
- 是否可以在 .Net 3.5 中进行通用控件? 2022-01-01
- Windows 喜欢在 LINUX 中使用 MONO 进行服务开发? 2022-01-01
- 在 C# 中异步处理项目队列 2022-01-01
- Azure Active Directory 与 MVC,客户端和资源标识同一 2022-01-01
- 使用 rss + c# 2022-01-01
- CanBeNull和ReSharper-将其用于异步任务? 2022-01-01