C# 服务器及;客户总是没有反应

C# 服务器及;客户总是没有反应,c#,sockets,freeze,C#,Sockets,Freeze,我不熟悉套接字,所以我尝试创建一个服务器和一个客户端来交换消息。我在C#中创建了一个,但它给了我一个奇怪的错误,一旦我启动服务器,它就会冻结,并显示“无响应”消息。。。当我连接服务器时,客户端也会发生同样的情况,但问题是当我关闭其中任何一个时。。另一个应用程序显示了更新,所以idk问题出在哪里这里是您使用的代码 服务器类 Socket Soc; static ushort MaxClients = 1000; static List<Socket> ClientList = new

我不熟悉套接字,所以我尝试创建一个服务器和一个客户端来交换消息。我在C#中创建了一个,但它给了我一个奇怪的错误,一旦我启动服务器,它就会冻结,并显示“无响应”消息。。。当我连接服务器时,客户端也会发生同样的情况,但问题是当我关闭其中任何一个时。。另一个应用程序显示了更新,所以idk问题出在哪里这里是您使用的代码

服务器类

Socket Soc;
static ushort MaxClients = 1000;
static List<Socket> ClientList = new List<Socket>(MaxClients);
static bool ServerStarted;
public Server()
{
    InitializeComponent();
    button1.Enabled = false;
    button2.Enabled = false;
}

private void button1_Click(object sender, EventArgs e) // Send
{
    string MessageToSend = textBox1.Text;
    byte[] Buffer = Encoding.Default.GetBytes(MessageToSend);
    foreach (var client in ClientList)
    {
        Soc.Send(Buffer, 0, Buffer.Length, SocketFlags.None);
    }
    textBox2.Text += " Message Sent To Clients : " + MessageToSend + Environment.NewLine;
}

private void button3_Click(object sender, EventArgs e) // Start
{
    StartServer("25.21.113.163", 5000);
}

private void button2_Click(object sender, EventArgs e) // Stop
{
    CloseServer();
}

private void button4_Click(object sender, EventArgs e) // Exit
{
    CloseServer();
    Application.Exit();
}

public void StartServer(string Ip, ushort Port)
{
    Soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    Soc.Bind(new IPEndPoint(IPAddress.Parse(Ip), Port));
    textBox2.Text += " Server Is Created On Ip : " + Ip + ", Port : " + Port + Environment.NewLine;
    Soc.Listen(MaxClients);
    textBox2.Text += " Server Is Listening to Clients Now... " + Environment.NewLine;
    ServerStarted = true;
    button1.Enabled = true;
    button2.Enabled = true;
    button3.Enabled = false;
    label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
    ReceiveData();
}

public void ReceiveData()
{
    while (true)
    {
        var Client = Soc.Accept();
        ClientList.Add(Client);
        label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
        textBox2.Text += " Client Located At Ip : " + Client.RemoteEndPoint.ToString().Split(':')[0].ToString() + " Is Now Connected To Server " + Environment.NewLine;
        while (true)
        {
            byte[] ReceivedBytes = new byte[1024];
            int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
            string MessageFromClient = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedDataLength);
            textBox2.Text += " Message Sent to Server : " + MessageFromClient + Environment.NewLine;
        }
    }
}

public void CloseServer()
{
    Soc.Close();
    ServerStarted = false;
    textBox2.Text += " Server Is Closed Now... " + Environment.NewLine;
    button3.Enabled = true;
    button2.Enabled = false;
    button1.Enabled = false;
}

我想知道我做错了什么?我怎样才能摆脱这两个应用程序愚蠢的“不响应”状态呢?

首先,让我们对代码进行更正,使其正常工作,感谢我提供了一些
异步套接字
教程,这比
同步
容易得多

您的问题在这一行:

public void ReceiveData()
{
    while (true)
    {
        var Client = Soc.Accept();
        ClientList.Add(Client);
        label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
        textBox2.Text += " Client Located At Ip : " + Client.RemoteEndPoint.ToString().Split(':')[0].ToString() + " Is Now Connected To Server " + Environment.NewLine;
        while (true)
        {
            byte[] ReceivedBytes = new byte[1024];
            int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
            string MessageFromClient = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedDataLength);
            textBox2.Text += " Message Sent to Server : " + MessageFromClient + Environment.NewLine;
        }
    }
}
原因有二: 1) 您必须侦听到单独线程的传入连接。 2) 您还必须在单独的线程中侦听每个客户机,这样它们就不会互相阻塞。在您的示例中,正在侦听客户端的第二个
while(true)
正在阻止服务器套接字接受其他客户端。将其重构为:

public void ReceiveData()
    {
        new Thread(() =>
        {
            while (true)
            {
                var Client = Soc.Accept();
                ClientList.Add(Client);
                label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
                textBox2.Text += " Client Located At Ip : " + Client.RemoteEndPoint.ToString().Split(':')[0].ToString() + " Is Now Connected To Server " + Environment.NewLine;

                new Thread(() =>
                {
                    while (true)
                    {
                        byte[] ReceivedBytes = new byte[1024];
                        int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
                        string MessageFromClient = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedDataLength);
                        textBox2.Text += " Message Sent to Server : " + MessageFromClient + Environment.NewLine;
                    }
                }).Start();
            }
        }).Start();
    }
这种方法为每个客户端使用单独的线程来处理从客户端接收到的数据

我还为客户端应用程序添加了代码:

public void ReceiveData()
    {
        new Thread(() =>
        {
            while (true)
            {
                byte[] ReceivedBytes = new byte[1024];
                int ReceivedBytesLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
                string ReceivedMessage = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedBytesLength);
                textBox1.Text += " Received Message From Server Is : " + ReceivedMessage + Environment.NewLine;
            }
        }).Start();
    }
将来,看看异步套接字,您将不再需要处理多线程问题。


编辑更新的客户端/ser

服务器应用程序会挂起,并且在启动后没有响应。。甚至连客户端连接都没有。。当我按下connect时,客户端也会被冻结,所有的发送/接收消息都在工作,但你看不到,除非你关闭其中任何一条消息。。你看到另一个应用程序更新了..我不知道Sync Socket是否设计得那么愚蠢,但我不太关心Sync,也不会使用em,但我需要知道的是,应用程序正在挂起复制更新的代码。注意:当从非UI线程更新文本框值时,您将收到错误,但简单的谷歌搜索将有所帮助;)它做得很好,但是当我发送客户端文本时,它给了我一个错误,说没有给idk地址这意味着什么似乎一切正常另一个问题,如果我使用异步套接字,我将不得不调用while(true)或者它处理与线程相关的所有事情?将25.21.113.163替换为localhost或127.0.0.1。当使用异步套接字时,您可以订阅套接字的特定事件,比如Received,并在套接字上调用ReceiveAsync,然后忘记它。套接字接收数据时,将触发相应的事件。
public void ReceiveData()
    {
        new Thread(() =>
        {
            while (true)
            {
                byte[] ReceivedBytes = new byte[1024];
                int ReceivedBytesLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
                string ReceivedMessage = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedBytesLength);
                textBox1.Text += " Received Message From Server Is : " + ReceivedMessage + Environment.NewLine;
            }
        }).Start();
    }