C# Winforms|无法从新类中的窗体获取值

g0czyy6m  于 2023-10-23  发布在  C#
关注(0)|答案(1)|浏览(173)

我正在尝试用C#在Winforms中创建一个异步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#新手,如果这是一个愚蠢的问题,我很抱歉。

w6lpcovy

w6lpcovy1#

如果你在监听器代码中看这一行

Form1 objects = new Form1();

您正在创建Form的一个全新示例,然后尝试使用此处的值。
相反,您需要将引用传递给原始Form。试试这个

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与xml 2类完全解耦会更好,只需将值传递给侦听器,如下所示:

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));
}

相关问题