C# 为什么在加载事件中连接到套接字时我的表单不出现?

C# 为什么在加载事件中连接到套接字时我的表单不出现?,c#,winforms,sockets,C#,Winforms,Sockets,此代码中的表单不显示。我怎样才能让它显示出来?通过控制台,一切正常 void Form1_Load(object sender, EventArgs e) { String host = Dns.GetHostName();//name kompa //ip pc IPAddress ip = Dns.GetHostByName(host).AddressList[0]; const

此代码中的表单不显示。我怎样才能让它显示出来?通过控制台,一切正常

 void Form1_Load(object sender, EventArgs e)
        {
            String host = Dns.GetHostName();//name kompa
            //ip pc
            IPAddress ip = Dns.GetHostByName(host).AddressList[0];
            const int port = 2222;
            label1.Text = host;
            label2.Text = "Сервер запущен на " + ip.ToString() + ":" + port.ToString();
            server.serversocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            server.serversocket.Bind(new IPEndPoint(ip, port));
            server.serversocket.Listen(100);

            //ошибочка в цикле
            while (server.work)
            {
                MessageBox.Show("dsff");
                Socket handle = server.serversocket.Accept();
                richTextBox1.AppendText("новое подключение" + handle.RemoteEndPoint.ToString());
                new user(handle);


            }

正如Hans Passant所说,您正在使用while循环阻塞GUI线程。那不行。事件必须尽快返回,不能无限期运行。在服务器停止工作之前,此表单加载无法返回


这是一个非常常见的错误,也是本世纪我们疯狂使用多任务和多线程的基本原因。如果没有它,您甚至无法再使用文字处理器。

您正在阻止ui线程。为同步套接字服务器使用单独的端口将是一个解决方案。另一个选项是使用异步套接字,以便在应用程序等待连接时不会阻止其执行。基于套接字代码

公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
InitSocketServer();
}
内部void InitSocketServer()
{
IPHostEntry ipHostInfo=Dns.Resolve(Dns.GetHostName());
var ipAddress=ipHostInfo.AddressList[0];
IPEndPoint localEndPoint=新IPEndPoint(ipAddress,11000);
尝试
{
套接字侦听器=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
Bind(localEndPoint);
听,听(100);
beginacept(AcceptCallback,listener);
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}
}
私有void AcceptCallback(IAsyncResult ar)
{
套接字侦听器=(套接字)ar.AsyncState;
套接字处理程序=listener.EndAccept(ar);
字符串数据=null;
while(true)
{
变量字节=新字节[1024];
int bytesRec=handler.Receive(字节);
data+=Encoding.ASCII.GetString(字节,0,bytesRec);
if(data.IndexOf(“”>-1)
{
打破
}
}
Show(handler.RemoteEndPoint+“:”+数据);
byte[]msg=Encoding.ASCII.GetBytes(数据);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
MessageBox.Show(“测试按钮点击”);
}
}

使用while()循环挂起UI线程是最基本的GUI编程错误之一。使用工作线程。此外,不建议在OnLoad中循环/长时间运行工作,表单在该阶段仍不显示。OnShown比其他人好。但请遵循@HansPassant的建议。
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        InitSocketServer();
    }

    internal void InitSocketServer()
    {
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        var ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
        try
        {
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            listener.Bind(localEndPoint);
            listener.Listen(100);
            listener.BeginAccept(AcceptCallback, listener);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void AcceptCallback(IAsyncResult ar)
    {
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        string data = null;

        while (true)
        {
            var bytes = new byte[1024];
            int bytesRec = handler.Receive(bytes);
            data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
            if (data.IndexOf("<EOF>") > -1)
            {
                break;
            }
        }


        MessageBox.Show(handler.RemoteEndPoint + " : " + data);

        byte[] msg = Encoding.ASCII.GetBytes(data);

        handler.Send(msg);
        handler.Shutdown(SocketShutdown.Both);
        handler.Close();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Test button click");
    }
}