简体   繁体   中英

How can I accept two or more clients in the same server c# tcp/ip

I'm trying to make my code accept two or more clients to my server program. Here is the code. I need help with the code on how to accept multiple clients at the same time. I got an error with the port. It says " Only one usage of each socket address (protocol/network address/port) is normally permitted "

namespace TCPServer { public partial class Form1 : Form {

    //Create TCP/IP Socket 
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    TcpListener mTCPListener;
    TcpClient mTCPClient = new TcpClient();
    NetworkStream serverStream;

    byte[] mRx;

    public Form1()
    {
        InitializeComponent();
    }

    void onCompleteAcceptTcpClient(IAsyncResult iar)
    {
        TcpListener tcpl = (TcpListener)iar.AsyncState;
        try
        {
            ThreadStart delegateR = new ThreadStart(() => 
            mTCPClient = tcpl.EndAcceptTcpClient(iar));

            Thread R = new Thread(delegateR);
            R.Start();
            printLine("Client Connected...");

            //Begin Asynchronous Read
            mRx = new byte[1024];
            mTCPClient.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, mTCPClient);

        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void btnStartListening_Click_1(object sender, EventArgs e)
    {
        try
        {
            IPAddress ipaddr;
            int nPort = 23000;

            #region Validating IP Address
            //if (!int.TryParse(tbPort.Text, out nPort))
            //{
            //    nPort = 23000;
            //}
            if (!IPAddress.TryParse(tbIPAddress.Text, out ipaddr))
            {
                MessageBox.Show("Invalid IP address supplied.");
                return;
            }
            #endregion




                mTCPListener = new TcpListener(ipaddr, nPort);
                //Start Listening
                mTCPListener.Start();

                //ThreadStart delegateT = new ThreadStart(() => { RefreshLot(lotId); });
                //Thread T = new Thread(delegateT);
                //T.Start();
                ThreadStart delegateT = new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
                Thread T = new Thread(delegateT);
                T.Start();
                //Begin accept tcp client (only one)
                //mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
                if (mTCPListener.Pending())
                {
                    nPort = nPort + 1;
                    mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener);
                }

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }


    void onCompleteReadFromTCPClientStream(IAsyncResult iar)
    {
        TcpClient tcpc;
        int nCountReadBytes = 0;
        string strRecv;
        try
        {
            tcpc = (TcpClient)iar.AsyncState;
            nCountReadBytes = tcpc.GetStream().EndRead(iar);

            if (nCountReadBytes == 0)
            {
                MessageBox.Show("Client disconnected.");
                return;
            }

            strRecv = Encoding.ASCII.GetString(mRx, 0, nCountReadBytes);
            printLine(strRecv);
            mRx = new byte[1024];
            tcpc.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, tcpc);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    public void printLine(string _strPrint)
    {
        tbConsoleOutput.Invoke(new Action<string>(doInvoke), _strPrint);
    }

    public void doInvoke(string _strPrint)
    {
        tbConsoleOutput.Text = _strPrint + Environment.NewLine + tbConsoleOutput.Text;
    }

    private void onCompleteWriteToClientStream(IAsyncResult iar)
    {
        try
        {
            TcpClient tcpc = (TcpClient)iar.AsyncState;
            tcpc.GetStream().EndWrite(iar);
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void btnSend_Click_1(object sender, EventArgs e)
    {
        byte[] tx = new byte[1024];
        if (string.IsNullOrEmpty(tbPayload.Text)) return;

        try
        {
            if (mTCPClient != null)
            {
                if (mTCPClient.Client.Connected)
                {

                    //This is the message that will be sent
                    tx = Encoding.ASCII.GetBytes("Server MESRII sent: " + tbPayload.Text + "  " + DateTime.Now);
                    mTCPClient.GetStream().BeginWrite(tx, 0, tx.Length, onCompleteWriteToClientStream, mTCPClient);
                }
            }
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void btnStartListening2_Click(object sender, EventArgs e)
    {

    }


}

You should create single TcpListener on your server, besause only one listener can use one port. When you getting new connection ( AcceptTcpClient method), you may begin new thread for messaging exchange with client. You can see good examples in this question

I was working in the code and took all the suggestions provided. What I did was Call the Start listening this way...

`private void btnStartListening_Click_1(object sender, EventArgs e) { try { index++;

            IPAddress ipaddr = IPAddress.Any;
            int x = Convert.ToInt32(tbPort.Text);
            int nPort = x;


            //#region Validating IP Address
            //if (!int.TryParse(tbPort.Text, out nPort))
            //{
            //    nPort = 23000;
            //}
            //if (!IPAddress.TryParse(tbIPAddress.Text, out ipaddr))
            //{
            //    MessageBox.Show("Invalid IP address supplied.");
            //    return;
            //}
            //#endregion

            if (nPort >= 23000)
            {
                nPort = nPort + 1;
                mTCPListener = new TcpListener(ipaddr, nPort);

                //Start Listening on port nPort + 1
                mTCPListener.Start();
                testingThreadStart.Add(new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener)));
                //ThreadStart delegateT = new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
                testingThread.Add(new Thread(testingThreadStart[index]));
                //Thread T = new Thread(delegateT);
                //T.Start();
                testingThread[index].Start();
                //Begin accept tcp client (only one)
                //mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
            }
            else
            {
                mTCPListener = new TcpListener(ipaddr, nPort + 1);

                //Start Listening on port 23000
                mTCPListener.Start();

                ThreadStart delegateT = new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
                Thread T = new Thread(delegateT);
                T.Start();

            }
        }`

Also added list of threads on the beginning of the code...

 List<ThreadStart> testingThreadStart = new List<ThreadStart>();
    List<Thread> testingThread = new List<Thread>();

and thats how it worked. If anyone need/want the complete code, I can post it. For future examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM