0

我最近一直在使用我在多线程上找到的代码来设计我的服务器

服务器启动正常并等待客户端,但是当客户端连接时,我得到了以下错误:

每个套接字地址(协议/网络地址/端口)通常只允许使用一次

编码:

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

听起来,您正在尝试运行两个侦听器 - 在“AcceptTcpClient”处停止的代码是原始侦听器:不应有其他线程同时尝试运行 tcpListener.Start。首先要做的是添加包含托管线程 ID 的日志记录——这样您就可以看到哪个线程正在做什么。您还可以查看调用 tcpListener.Start 的代码的堆栈跟踪以了解它的来源,因为这不应该发生(此时侦听器已经在运行)。

作为设计要点:不推荐每个客户端线程。

于 2013-11-03T11:15:43.990 回答
0

在 ClientComm 中创建新表单时,您将启动一个新的 listenThread。

Form1 p = new Form1();

如前所述,您只能在端口上侦听一次,while 循环将为新连接生成线程。您应该尝试捕获acceptTCPClient,例如,停止将给出您需要捕获的异常。

于 2013-11-03T17:45:20.123 回答