如何在同一服务器c#tcp / ip中接受两个或更多客户端

时间:2017-12-14 00:45:56

标签: c# sockets tcp

我试图让我的代码接受两个或更多客户端到我的服务器程序。这是代码。我需要有关如何同时接受多个客户端的代码的帮助。我的端口出错了。它说" 通常只允许使用每个套接字地址(协议/网络地址/端口)"

命名空间TCPServer {     公共部分类Form1:表格     {

    //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)
    {

    }


}

2 个答案:

答案 0 :(得分:0)

您应该在服务器上创建单个TcpListener,因为只有一个侦听器可以使用一个端口。 当您获得新连接(AcceptTcpClient方法)时,您可以开始与客户端进行消息交换的新线程。 您可以在this question

中看到很好的示例

答案 1 :(得分:0)

我正在使用代码并提供了所有提供的建议。我做的是用这样的方式打电话开始......

`private void btnStartListening_Click_1(object sender,EventArgs e)         {             尝试             {                 索引++;

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

            }
        }`

还在代码的开头添加了线程列表...

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

这就是它的工作原理。如果有人需要/想要完整的代码,我可以发布它。对于未来的例子。