多线程服务器Socket Exception被低估了

时间:2013-11-03 10:25:23

标签: c# sockets

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

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

  

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

代码:

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

退出,并在

显示错误
this.tcpListener.Start();

我做错了什么?

2 个答案:

答案 0 :(得分:0)

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

作为设计点:不建议使用每个客户端的线程。

答案 1 :(得分:0)

在ClientComm中创建新表单时启动新的listenThread。

Form1 p = new Form1();

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