C# Form. Changing a Client / Server chat room so clients can speak with one another

1k views Asked by At

This question has probably been asked before. Okay so I am still learning how to program with sockets but I was wondering how you could change the client / server so that clients can talk amongst themselves as well as the server talking to the clients like an administrator. I have found various things on Handle Clients but these were for Console Apps and not C# Windows Forms, I tried to covert them but with no luck.

This is my server code so far.

namespace Socket_Server
{

public partial class Form1 : Form
{
    const int MAX_CLIENTS = 30;

    public AsyncCallback pfnWorkerCallBack;
    private Socket m_mainSocket;
    private Socket[] m_workerSocket = new Socket[30];
    private int m_clientCount = 20;
    string readData = null;

    public Form1()
    {
        InitializeComponent();
        textBoxIP.Text = GetIP();
    }
    private void buttonStartListen_Click(object sender, EventArgs e)
    {
        try
        {
            if (textBoxPort.Text == "")
            {
                MessageBox.Show("Please enter a Port Number");
                return;
            }
            string portStr = textBoxPort.Text;
            int port = System.Convert.ToInt32(portStr);.
            m_mainSocket = new Socket(AddressFamily.InterNetwork,
                                      SocketType.Stream,
                                      ProtocolType.Tcp);
            IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);
            m_mainSocket.Bind(ipLocal);
            m_mainSocket.Listen(4);
            m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
            UpdateControls(true);

        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    private void UpdateControls(bool listening)
    {
        buttonStartListen.Enabled = !listening;
        buttonStopListen.Enabled = listening;
    }

    public void OnClientConnect(IAsyncResult asyn)
    {
        try
        {
            m_workerSocket[m_clientCount] = m_mainSocket.EndAccept(asyn);
            WaitForData(m_workerSocket[m_clientCount]);
            ++m_clientCount;    
            String str = String.Format("Client # {0} connected", m_clientCount);
            Invoke(new Action(() =>textBoxMsg.Clear()));
            Invoke(new Action(() =>textBoxMsg.AppendText(str)));
            m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
        }
        catch (ObjectDisposedException)
        {
            System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }

    }

    public class SocketPacket
    {
        public System.Net.Sockets.Socket m_currentSocket;
        public byte[] dataBuffer = new byte[1024];
    }

    public void WaitForData(System.Net.Sockets.Socket soc)
    {
        try
        {
            if (pfnWorkerCallBack == null)
            {
                pfnWorkerCallBack = new AsyncCallback(OnDataReceived);
            }
            SocketPacket theSocPkt = new SocketPacket();
            theSocPkt.m_currentSocket = soc;// could be this one!!!
            soc.BeginReceive(theSocPkt.dataBuffer, 0,
                               theSocPkt.dataBuffer.Length,
                               SocketFlags.None,
                               pfnWorkerCallBack,
                               theSocPkt);
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }

    }

    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            SocketPacket socketData = (SocketPacket)asyn.AsyncState;
            int iRx = 0;
            iRx = socketData.m_currentSocket.EndReceive(asyn);
            char[] chars = new char[iRx + 1];
            System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(socketData.dataBuffer,
                                     0, iRx, chars, 0);
            System.String szData = new System.String(chars);
            Invoke(new Action(() => richTextBoxSendMsg.AppendText(szData)));
            Invoke(new Action(() => richTextBoxSendMsg.AppendText(Environment.NewLine)));
            WaitForData(socketData.m_currentSocket);
        }
        catch (ObjectDisposedException)
        {
            System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    private void buttonSendMsg_Click(object sender, EventArgs e)
    {
        try
        {
            Object objData = txtBoxType.Text;
            byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
            for (int i = 0; i < m_clientCount; i++)
            {
                if (m_workerSocket[i] != null)
                {
                    if (m_workerSocket[i].Connected)
                    {
                        m_workerSocket[i].Send(byData);
                        txtBoxType.Clear();
                    }
                }
            }

        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    private void buttonStopListen_Click(object sender, EventArgs e)
    {
        CloseSockets();
        UpdateControls(false);
    }

    String GetIP()
    {
        String strHostName = Dns.GetHostName();
        IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);

        String IPStr = "";

        foreach (IPAddress ipaddress in iphostentry.AddressList)
        {
            if (ipaddress.IsIPv6LinkLocal == false)
            {
                IPStr = IPStr + ipaddress.ToString();
                return IPStr;
            } 

        }
        return IPStr;
    }

    private void buttonClose_Click(object sender, EventArgs e)
    {
        CloseSockets();
        Close();
    }

    void CloseSockets()
    {
        if (m_mainSocket != null)
        {
            m_mainSocket.Close();
        }
        for (int i = 0; i < m_clientCount; i++)
        {
            if (m_workerSocket[i] != null)
            {
                m_workerSocket[i].Close();
                m_workerSocket[i] = null;
            }
        }
    }
}

}

Thank you in advance.

0

There are 0 answers