0

我使用msdn 上的这篇文章作为主要助手编写了我的代码

我的代码:

    private ManualResetEvent _AllDone = new ManualResetEvent(false);

    internal void Initialize(int port,string IP)
    {
        IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
        Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _Accpt.Bind(_Point);
        _Accpt.Listen(2);

        while (true)
        {
            _AllDone.Reset();
            _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
            _AllDone.WaitOne(); <<crash here
        }

    }

这就是发生的情况,我在 BeginAccept 处设置了一个断点(我认为有问题),但它正常执行。但是,当我尝试执行“_AllDone.WaitOne()”时 - 服务器崩溃。

如果 _allDone 不能在 win32 表单应用程序中使用 - 我如何制作我的项目?

编辑

我忘了提到我在Accept()中写了_AllDone.Reset(),但它没有去那里,我在那里设置了一个断点,但它不会去。

    private void Accept(IAsyncResult async)
    {
        _AllDone.Set();
        Socket _Accpt = (Socket)async.AsyncState;
        Socket _Handler = _Accpt.EndAccept(async);

        StateObject _State = new StateObject();
        _State.workSocket = _Handler;

        _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);

    }
4

2 回答 2

1

因此,如果我做对了,您希望在收到套接字连接后立即重新启动Accept,而不是等到Accept完成,这就是为什么您不使用同步版本的Accept.

所以您是说当您将套接字连接到指定的地址和端口时它不会触发您的 Accept 方法?因为这就是 Accept 所做的:它接受一个新的传入连接,等待客户端连接。因此,这可能就是您认为它“崩溃”以及它永远不会在您的 Accept 方法中到达您的代码的原因。

提示:也许也看看Socket.AcceptAsync

编辑:要设置一个监听传入连接的异步服务器,您不需要任何 ManualWaitEvent:

internal void Initialize(int port,string IP) {
    IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
    Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    _Accpt.Bind(_Point);
    _Accpt.Listen(2);
    _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
}

private void Accept(IAsyncResult async) {
    Socket _Accpt = (Socket)async.AsyncState;
    Socket _Handler;
    try {
        _Handler = _Accpt.EndAccept(async);
    } finally {
        _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
    }

    StateObject _State = new StateObject();
    _State.workSocket = _Handler;

    _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);
}

注意:您还需要一个退出条件,以便不调用 BeginAccept(例如,当您想要关闭服务器时)。

于 2009-04-29T14:55:37.043 回答
0

我认为 Lucero 想说的是,该应用程序运行正常,您可能会问为什么。

好吧,当您使用服务器端套接字应用程序时,您基本上要做的就是要求服务器侦听端口并等待连接到达。当连接到达时,您将执行其余的代码。

Lucero 的意思是,当没有消息到达服务器时,服务器会一直等待和等待,这可能会像冻结一样寻找您。

您的代码中是否存在这种情况?

于 2009-08-21T17:15:32.660 回答