1

I'm new to sockets so I tried to create a server and a client that exchange messages. I created one in C# but it gave me weird error which it once I start the server it freezes and "not responding" message appears ... same happens with client when I connect the server but the problem is when I close any of them .. the other application have the updates shown up so idk what the problem is anyways here are the codes U used

Server class

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

Client class

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

I'd like to know what did I do wrong? And how can I get rid of that silly "Not Responding" state of both applications?

4

1 回答 1

0

First, Let's make a corrections on your code so that it works, thank I'd give some Asynchronous Socket tutorials which is a lot easier than Synchronous.

Your problem is in this line:

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

This is because of 2 reasons: 1) You must listen to incoming connection to a separate thread. 2) You must listen to each client in a separate thread too, so they don't block each other. In your example second while(true) which is listening for client is blocking server socket from accepting other clients. Refactor it to:

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

This approach uses separate thread for each client to process received data from client.

I also added code for client app:

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

In the future have a look Asynchronous Sockets and you will no more need handling multithreading issues. http://msdn.microsoft.com/en-us/library/fx6588te.aspx http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx

EDIT Updated client/ser

于 2013-09-25T10:31:56.313 回答