2017-12-14 10 views
0

내 코드가 두 개 이상의 클라이언트를 허용하도록 서버 프로그램에 지정하려고합니다. 여기에 코드가 있습니다. 여러 클라이언트를 동시에 수락하는 방법에 대한 코드에 도움이 필요합니다. 나는 항구에 오류가있다. 양식 {동일한 서버에 두 개 이상의 클라이언트를 허용하는 방법 C# tcp/ip

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

    } 


} 
+1

이전 게시글에 대한 내 답변의 문제는 무엇인가요? https://stackoverflow.com/questions/47799387/c-sharp-how-to-accept-multiple-clients-in-one-tcp-server 내 첫 번째 의견에 동일한 포트 번호로 동일한 IP 주소에서 두 개의 연결을 가질 수 없습니다. 동일한 IP에서 테스트하려면 두 개의 포트 번호가 필요합니다. 따라서 두 개의 다른 포트 번호로 두 개의 Listener를 작성하십시오. 두 Listener 모두 동일한 Accept Event를 사용합니다. 테스트 후 두 번째 리스너를 제거 할 수 있습니다. 대규모 네트워크에서 여러 포트 번호와 여러 서버를 시도하는 클라이언트의 연결과 일반적입니다. – jdweng

+0

다른 포트 번호를 어떻게 할당 할 수 있습니까? 두 클라이언트 대신에 다른 클라이언트를 가져 오면 ... – Christian

+0

서버 포트 번호는 동적으로 할당되지 않습니다. 이들은 항상 하나의 포트 번호 또는 일련의 포트 번호로 사전 할당됩니다. 클라이언트 측에서는 다른 응용 프로그램이 동일한 서버에 동일한 포트 번호를 사용하고 있지 않은지 확인하거나 한 포트 번호에서 연결을 시도하고 실패 할 경우 해당 범위의 다음 포트 번호를 시도합니다. TCP를 사용하면 동일한 세 가지 매개 변수로 단 하나의 연결 만 가질 수 있습니다. 1) 소스 IP 주소 2) 대상 IP 주소 3) 포트 번호. – jdweng

답변

0

당신은해야한다 : 그것은

네임 스페이스 tcpserver는 { 공공 부분 Form1 클래스 "각 소켓 주소 (프로토콜/네트워크 주소/포트) 하나 개의 사용이 일반적으로이 허용됩니다"라고 하나의 리스너 만 하나의 포트를 사용할 수 있기 때문에 서버에 단일 TcpListener을 작성하십시오. 새 연결 (AcceptTcpClient 메서드)을 얻으면 클라이언트와 메시징 교환을위한 새 스레드를 시작할 수 있습니다. 좋은 예제를 볼 수 있습니다 this question

0

나는 코드에서 작업 중이며 제공된 모든 제안을 다했습니다. 내가 한 것이 시작 ...

`개인 무효 btnStartListening_Click_1 (개체 보낸 사람, EventArgs입니다 전자)이 방법을 듣고 전화했다 { 이 { 인덱스를 시도 ++;

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

을 스레드의 목록을 추가하고 어떻게 작동하는지 이잖아. 누구든지 완전한 코드를 필요로하거나 원한다면, 나는 그것을 게시 할 수 있습니다. 향후 예제.