C# Winforms |我无法从新课程中的表单获取值

问题描述 投票:0回答:1

我正在尝试在 Winforms 中使用 C# 制作异步 TCP 服务器/客户端。我已经从控制台完成了,一切都很好。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void StartListener_Click(object sender, EventArgs e)
        {
            AsyncSocketListener.StartListener();
        }

        public class ObjectState { 
            public Socket socket = null;
            public const int bufferSize = 1024;
            public byte[] buffer = new byte[bufferSize];
            public StringBuilder sb = new StringBuilder();
        }

        public class AsyncSocketListener { 
            public static ManualResetEvent completed = new ManualResetEvent(false);
            
            public static void StartListener()
            {
                Form1 objects = new Form1();
                byte[] bytes = new byte[1024];

                int port = int.Parse(objects.ServerPort.Text);
                IPAddress ip = IPAddress.Parse(objects.ServerIP.Text);
                IPEndPoint ep = new IPEndPoint(ip, port);
                Socket listener = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                try
                {
                    listener.Bind(ep);
                    listener.Listen(999999999);

                    while (true) { 
                        completed.Reset();
                        MessageBox.Show("Listener started: Waiting for incoming connections", "Listener started", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
                    }
                } 

                catch (Exception a) {
                    MessageBox.Show(a.Message, "Error - Listener failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            private static void AcceptCallBack(IAsyncResult ar) { 
                completed.Set();
                Socket listener = (Socket) ar.AsyncState;
                Socket handler = listener.EndAccept(ar);

                ObjectState state = new ObjectState();
                state.socket = handler;
                handler.BeginReceive(state.buffer, 0, ObjectState.bufferSize, 0, new AsyncCallback(ReadCallBack), state);
            }

            private static void ReadCallBack(IAsyncResult ar)
            {
                string content = String.Empty;
                ObjectState state = (ObjectState) ar.AsyncState;
                Socket handler = state.socket;
                int bytesRead = handler.EndReceive(ar);
                if (bytesRead > 0)
                {
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>", StringComparison.Ordinal) > -1)
                    {
                        MessageBox.Show($"Read: {content.Length} bytes from socket Data: {content}", "Socket data", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        Send(handler, content);
                    }
                    else
                    {
                        handler.BeginReceive(state.buffer, 0, ObjectState.bufferSize, 0, new AsyncCallback(ReadCallBack), state);
                    }
                }
            }

            private static void Send(Socket handler, String content)
            {
                byte[] byteData = Encoding.ASCII.GetBytes(content);
                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
            }

            private static void SendCallback(IAsyncResult ar)
            {
                try { 
                    Socket handler = (Socket) ar.AsyncState;
                    int byteSent = handler.EndSend(ar);
                    MessageBox.Show($"Sent: {byteSent} to client", "Socket data", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }

                catch (Exception e) {
                    MessageBox.Show(e.Message, "Socket Callback Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

        }
    }
}

使用 GUI 执行此操作时,我的服务器出现问题。在我的

AsyncSocketListener
类中,
StartListener
函数无法捕获 GUI 文本框中传递的值。

Form1 objects = new Form1();
byte[] bytes = new byte[1024];

int port = int.Parse(objects.ServerPort.Text);
IPAddress ip = IPAddress.Parse(objects.ServerIP.Text);
IPEndPoint ep = new IPEndPoint(ip, port);

知道这是怎么回事吗?为什么我无法从班级获取值?

我是 C# 新手,如果这是一个愚蠢的问题,我很抱歉。

c# winforms asynchronous tcplistener tcpserver
1个回答
0
投票

因此,如果您查看此行的侦听器代码

Form1 objects = new Form1();

您正在创建一个全新的表单实例,然后尝试使用此处的值。

您需要将引用传递给原始表单。所以试试这个;

public class AsyncSocketListener 
{ 
        public static ManualResetEvent completed = new ManualResetEvent(false);

        //Amend this to accept a reference to the Form1 object                
        public static void StartListener(Form1 objects)
        {
            //Rest of code as before

然后像这样传递引用;

 private void StartListener_Click(object sender, EventArgs e)
 {
        AsyncSocketListener.StartListener(this);
 }

也许您还可以采取其他一些措施来改进代码(请参阅注释),包括将“

objects
”重命名为更有意义的名称,例如“
form
”。

事实上,最好将

Form1
与 Listener 类完全解耦,然后将值传递给侦听器,如下所示;

 public static void StartListener(IPAddress ip, int port)
 {         
     byte[] bytes = new byte[1024];
      IPEndPoint ep = new IPEndPoint(ip, port);
     //Rest of code as before

像这样传递引用;

private void StartListener_Click(object sender, EventArgs e)
{
    AsyncSocketListener.StartListener(IPAddress.Parse(this.ServerIP.Text), int.Parse(this.ServerPort.Text));
}
© www.soinside.com 2019 - 2024. All rights reserved.