C#程序挂起在Socket.Accept()上

C#程序挂起在Socket.Accept()上,c#,multithreading,sockets,C#,Multithreading,Sockets,我创建了一个服务器“中间人”应用程序,它使用套接字和多线程技术(ServerListener在新线程中运行)。我很早就发现,当我使用Socket.Accept()方法时,程序会无限期挂起,等待连接发生。问题是,据我所知,没有理由不这样做 我花了一天的大部分时间尝试了很多不同的东西来让它工作,但某处发生了变化,因为它突然开始工作了一段时间。然而,当我意外地为客户机应用程序选择了不同于“localhost”的数据源时,问题再次出现。我曾尝试在没有防火墙或防病毒软件的情况下运行该程序,但没有成功。客户

我创建了一个服务器“中间人”应用程序,它使用套接字和多线程技术(ServerListener在新线程中运行)。我很早就发现,当我使用Socket.Accept()方法时,程序会无限期挂起,等待连接发生。问题是,据我所知,没有理由不这样做

我花了一天的大部分时间尝试了很多不同的东西来让它工作,但某处发生了变化,因为它突然开始工作了一段时间。然而,当我意外地为客户机应用程序选择了不同于“localhost”的数据源时,问题再次出现。我曾尝试在没有防火墙或防病毒软件的情况下运行该程序,但没有成功。客户端程序设置为在端口10000上连接。这是我的密码:

    public void ServerListener() {
        UpdateStatus("Establishing link to server");
        server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Bind(new IPEndPoint(IPAddress.Any, defaultPort));
        server.Listen(queue);
        UpdateStatus("Accepting Connections");
        while (true) {
            Socket client = default(Socket);
            try {
                client = server.Accept();
                if (client != null) {
                    ++count;
                    UpdateCount(count.ToString());
                    new Thread(
                    () => {
                        Client myclient = new Client(client, defaultPort, this);
                    }
                    ).Start();
                }
            }
            catch( Exception ex ){
                MessageBox.Show(ex.ToString());
                client.Close();
            }
        }
    }
它将一直正常运行,直到server.Accept(),然后挂起。如前所述,它在一段时间前确实有效,但现在再次挂起。我试着查看是否有其他程序正在使用端口10000,但它们没有。我和一个朋友反复讨论这个问题,但我们没有发现问题所在。请帮忙


编辑澄清一下,我知道Accept是一个阻塞调用。客户端程序在端口10000上建立连接,但该程序继续等待Accept,就好像什么都没发生一样。它确实工作了一段时间,所以我知道从客户端程序的一端开始,连接就像应该的那样工作。然而,我无法理解为什么这个程序现在表现得好像连接从未发生过一样,并继续故意等待Accept。

Accept
块。如果在等待其他客户端连接时要执行其他操作,可以:

  • 在另一个线程或更好的线程中运行
    ServerListener
    -长时间运行的任务:

    using System.Threading.Tasks;
    ...
    Task.Factory.StartNew(ServerListener, TaskCreationOptions.LongRunning);
    
  • 使用使用的。为此,您需要创建一个新的
    SocketAsyncEventArgs
    实例,设置其值并将其传递给
    socket.acceptSync


  • 故意接受
    块。如果在等待其他客户端连接时要执行其他操作,可以:

  • 在另一个线程或更好的线程中运行
    ServerListener
    -长时间运行的任务:

    using System.Threading.Tasks;
    ...
    Task.Factory.StartNew(ServerListener, TaskCreationOptions.LongRunning);
    
  • 使用使用的。为此,您需要创建一个新的
    SocketAsyncEventArgs
    实例,设置其值并将其传递给
    socket.acceptSync



  • 但这就是它的工作原理
    Accept
    正在阻止呼叫。也许我应该更清楚一点。Accept是阻塞的,但一旦建立连接,它就应该继续,对吗?连接来自客户端程序,但accept一直在等待,好像什么都没发生一样,直到循环中下一次调用
    accept
    。听起来您在调试多线程代码时遇到了问题。似乎您希望接受单个连接。如果是这样的话,为什么还要循环呢?一次可能有多个客户端连接,但这就是它的工作原理
    Accept
    正在阻止呼叫。也许我应该更清楚一点。Accept是阻塞的,但一旦建立连接,它就应该继续,对吗?连接来自客户端程序,但accept一直在等待,好像什么都没发生一样,直到循环中下一次调用
    accept
    。听起来您在调试多线程代码时遇到了问题。似乎您希望接受单个连接。如果是这样的话,为什么要循环呢?一次可能有多个客户端连接为什么长时间运行的任务更好?这是一个更高级别的抽象,当有人在理解一个概念时,抽象尤其有用。ServerListener正在另一个线程中运行。尝试使用Acceptsync方法,但很难看到如何将其应用于这种情况;我的SocketAsyncEventArgs会有什么样的值?弄明白了,AcceptAsync最终确实很有用。谢谢@Gusdor
    TaskCreationOptions.LongRunning
    向TaskFactory发出信号,表示您将提供给我的线程不太可能很快返回。这意味着任务工厂不再从线程池中获取线程,而是创建了一个新线程。为什么长时间运行的任务更好?这是一个更高级别的抽象,当有人在理解概念时,抽象尤其有用。ServerListener正在另一个线程中运行。尝试使用Acceptsync方法,但很难看到如何将其应用于这种情况;我的SocketAsyncEventArgs会有什么样的值?弄明白了,AcceptAsync最终确实很有用。谢谢@Gusdor
    TaskCreationOptions.LongRunning
    向TaskFactory发出信号,表示您将提供给我的线程不太可能很快返回。这意味着任务工厂不再从线程池中获取线程,而是创建了一个新线程。