0

私は最近、マルチスレッドで見つけたコードを使用して、サーバーを設計しています

サーバーは正常に起動し、クライアントを待機しますが、クライアントが接続すると次のエラーが発生します。

通常、各ソケット アドレス (プロトコル/ネットワーク アドレス/ポート) の使用は 1 つだけ許可されます。

コード:

public partial class Form1 : Form
{
    Server s;
    public Form1()
    {
        InitializeComponent();  

        s = new Server(this);
        s.StartTcpServer(); 
    }
    private void Stop_Btn_Click(object sender, EventArgs e)
    {
       s.StopListenForClients();
    }
    public void addButton(int x, int y, String text)
    {
        Button btn = new Button();
        btn.Size = new Size(50, 50);
        btn.Location = new Point(x, y);
        btn.Text = text;
        btn.Visible = true;
        this.Controls.Add(btn);
    }
}
class Server
{
    public event EventHandler recvdChanged;
    private TcpListener tcpListener;
    private Thread listenThread;
    private string recvd;
    Form1 _f1parent;
    public Server(Form1 par)
    {
        _f1parent = par;
    }
    public string getsetrecvd
    {
        get { return this.recvd; }
        set
        {
            this.recvd = value;
            if (this.recvdChanged != null)
                this.recvdChanged(this, new EventArgs());
        }
    }
    public void StartTcpServer()
    {
        this.tcpListener = new TcpListener(IPAddress.Any, 8000);
        this.listenThread = new Thread(new ThreadStart(ListenForClients));
        this.listenThread.Start();
    }
  static  Boolean b = false;
    private void ListenForClients()
    {
      //where are recive the error 
        this.tcpListener.Start();

        while (true)
        {
            //blocks until a client has connected to the server
            TcpClient client = this.tcpListener.AcceptTcpClient();
            if (client.Connected)
            {
                b = true;
            //    MessageBox.Show(client.Client.RemoteEndPoint + " Has Connected.");
            }

            //create a thread to handle communication 
            //with connected client
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            clientThread.Start(client);
            b = false;   
        }
    }
    public void StopListenForClients()
    {
        tcpListener.Stop();
    }
    private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();

        byte[] message = new byte[4096];
        int bytesRead;
        Form1 p = new Form1();
        while (true)
        {
            bytesRead = 0;

            try
            {
                //blocks until a client sends a message
                bytesRead = clientStream.Read(message, 0, 4096);

            }
            catch
            {
                //a socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                //the client has disconnected from the server
                break;
            }

            //message has successfully been received
            ASCIIEncoding encoder = new ASCIIEncoding();
            getsetrecvd = encoder.GetString(message, 0, bytesRead);
            if (recvd != "e")
            {
            }
            else
            {
                break;
            }
        }

        tcpClient.Close();
    }
}

私はプログラムをデバッグし、ListenForClients() で while ループを実行し、クライアントを受け入れた後、再び while ループを実行しますが、

TcpClient client = this.tcpListener.AcceptTcpClient();

whileを終了し、エラーを表示します

this.tcpListener.Start();

私は何を間違っていますか?

4

2 に答える 2

0

その音で、2 つのリスナーを実行しようとしています。「AcceptTcpClient」で停止したコードが元のリスナーです。同時に tcpListener.Start を実行しようとするスレッドは他にないはずです。最初に行うことは、マネージド スレッド ID を含むログを追加することです。これにより、どのスレッドが何をしているかを確認できます。tcpListener.Start を呼び出すコードのスタック トレースを調べて、それがどこから来たのかを確認することもできます。これは、発生してはならないためです(リスナーはこの時点で既に実行されています)。

設計上のポイント: クライアントごとのスレッドは推奨されません。

于 2013-11-03T11:15:43.990 に答える