[英]TCP / Server I can from another class call the components of Form1
I have this example as a server.我有这个例子作为服务器。 The question that only works well for me on console.在控制台上只对我有效的问题。 I want to pass it to windows Form.我想将它传递给 Windows 窗体。 And I don't know how to apply it.而且我不知道如何应用它。
Because I understand that it is bad practice from another class such as creating a Form1 Method and using a Form1 object in the Server class.因为我知道这是另一个类的不好做法,例如创建 Form1 方法并在 Server 类中使用 Form1 对象。
As if in the server class I call the textbox or things like that.好像在服务器类中我调用文本框或类似的东西。
The question that I think I would have to adapt all the code back for windows Form?我认为我必须将所有代码改回 Windows 窗体的问题?
Or stop using the classes and use the typical TcpClient, TpcListener as in the videos that declare it at the moment in Form1.或者停止使用这些类并使用典型的 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) { }
}
}
}
The problem is this.问题是这个。 If I have Form1.如果我有 Form1.
As I relate it, as I do eg.正如我所涉及的那样,就像我所做的那样。 Every time a new Client is created it is added by a list box from the Server class.每次创建一个新的客户端时,它都会通过来自 Server 类的列表框添加。 In theory you can't or if you can or is it bad practice?理论上你不能,或者如果你可以,或者这是不好的做法?
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();
}
}
}
How could it be done without being in the main WindForm class如果不在主要的 WindForm 类中怎么做
Here are steps to help you start.以下是帮助您开始的步骤。
WinForms
project in VisualStudio.在 VisualStudio 中创建一个新的WinForms
项目。Program.cs
that contains the Main()
method.您应该拥有包含Main()
方法的Program.cs
。 You do not need to change it.您不需要更改它。 This is what causes the Form1
to load and display.这就是导致Form1
加载和显示的原因。[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
Form1.cs
and select View Code
to see the code behind page.您可以右键单击Form1.cs
并选择View Code
以查看代码隐藏页面。InityializeConponent()
method that creates all of your GUI "stuff".在那里,您将拥有具有InityializeConponent()
方法的构造函数,该方法可创建您的所有 GUI“东西”。Form1
-> Properties
and add a new function to the Load
打开您的 GUI 设计器,转到Form1
-> Properties
并将一个新函数添加到Load
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
.您的服务器可以转到一个新类,该类可以位于新文件中,例如Server.cs
。 Just make sure that WaitForConnection()
is public
.只需确保WaitForConnection()
是public
。This should get you started.这应该让你开始。 When you run into an issue, just create a new question on SO and make sure to add your latest code.当您遇到问题时,只需在 SO 上创建一个新问题并确保添加您的最新代码。
Some suggestions:一些建议:
delegate
to communicate between Server and the GUI使用delegate
在服务器和 GUI 之间进行通信Form1_Close
event and shut down your server there correctly确保有一个Form1_Close
事件并在那里正确关闭您的服务器
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.