服务器&客户始终无响应

时间:2013-09-25 09:08:35

标签: c# sockets freeze

我是套接字的新手,所以我尝试创建一个服务器和一个交换消息的客户端。我在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;
}

客户端类

Socket Client;
public Form1()
{
    InitializeComponent();
    button1.Enabled = false;
    button2.Enabled = false;
}

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

private void button2_Click(object sender, EventArgs e) // LogOut
{
    ClientClose();
}

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

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

public void ConnectToServer(string Ip, ushort Port)
{
    try
    {
        Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Client.Connect(Ip, Port);
        textBox1.Text += " You Are Now Connected To Server Hosted On Ip : " + Client.RemoteEndPoint + Environment.NewLine;
        button1.Enabled = true;
        button2.Enabled = true;
        button3.Enabled = false;
        ReceiveData();
    }
    catch
    {
        textBox1.Text += " Server In Offline Now " + Environment.NewLine;
    }
}

public void ReceiveData()
{
    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;
    }
}

public void ClientClose()
{
    button1.Enabled = false;
    button2.Enabled = false;
    button3.Enabled = true;
    Client.Dispose();
    Client.Close();
    textBox1.Text += " You Are Disconnected From Server" + Environment.NewLine;
}

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

1 个答案:

答案 0 :(得分:0)

首先,让我们对您的代码进行更正以使其正常工作,谢谢我提供一些Asynchronous Socket教程,这比Synchronous容易得多。

你的问题在这一行:

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

将来看看Asynchronous Sockets,您将不再需要处理多线程问题。 http://msdn.microsoft.com/en-us/library/fx6588te.aspx http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx

编辑更新了客户/服务