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

时间:2014-07-15 06:16:52

标签: c# multithreading sockets

我创建了一个服务器“midman”应用程序,它使用套接字和多线程技术(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,就好像什么都没发生一样。它确实工作了一段时间,所以我知道连接的工作方式与客户端程序的结果一样。但是,我无法理解为什么这个程序现在表现得像连接永远不会发生,并继续等待接受。

2 个答案:

答案 0 :(得分:3)

Accept故意阻止。如果您想在等待其他客户连接时做其他事情,您可以:

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

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

答案 1 :(得分:0)

如果它在localhost中工作,但在真实网络上没有,我相信,你遇到了数据包丢失。也许您期望当数据包丢失时,tcp将自动重新传输。它不像那样工作。

EG。如果发送非常小的数据包(1个字符),并且数据包被丢弃,客户端将不会重新发送丢弃的数据包,服务器将不会请求客户端重新发送。

您可以阅读tcp可靠的数据传输,了解它的实际工作方式。接受异步只接受异步,它不会解决你有关丢失数据包的问题。