如果在套接字关闭后调用Socket.BeginSend,应用程序崩溃而不抛出异常

时间:2011-10-13 12:51:16

标签: c# sockets asynchronous crash send

我正在编写一个套接字应用程序,它同时异步轮询多个服务器,并向用户报告其状态的任何变化。到目前为止一切正常,除了一个我似乎无法弄清楚的小虫子。

服务器每10秒创建一堆套接字,然后调用异步连接。然后由ProcessConnectionComplete(IAsyncResult iar)方法处理,然后调用Socket.BeginReceive和Socket.Begin发送。然后用另一种方法处理任何接收的数据。

然后,在创建下一波套接字之前的10秒结束时,任何尚未接收数据并关闭的套接字都会被循环强行关闭。

我遇到的问题是,如果套接字恰好在调用Socket.BeginSend方法之前关闭(即有人通过网络电缆跳闸,或者另一端的服务器崩溃),程序将退出而不执行(错误代码0),当它应该抛出异常时。这是代码:

private static void ProcessConnectionComplete(IAsyncResult iar)
{
    SocketState state = iar.AsyncState as SocketState;
    if (state.Socket.Connected)
    {
        // start waiting for a reply
        state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, new AsyncCallback(frm_Server_Poll.ProcessAsyncReceive), state);

        //state.Socket.Close(); // if socket is closed after .Connected check and before BeginSend, crash occurs
        try
        {
            // send message
            state.Socket.BeginSend(new byte[] { (byte)'\xfe' }, 0, 1, SocketFlags.None, null, state);
        }
        catch (Exception ex) // Never called, EXCEPTION WHERE ARE YOU???
        {
            throw (ex);
        }
    }
    else
    {
        state.ServerInfo.connected = false;
    }
}

为什么会这样?我有一些想法,它与使用异步调用处理线程的方式有关,但不知道如何捕获异常。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

调用frm_Server_Poll.ProcessAsyncReceive时,回调(Socket.EndReceive)中应发生异常。

同样,对于send,在调用Socket.EndSend时,异常应该在其回调中发生。但是,您的BeginSend没有用于处理错误的回调。

我无法确定,但我怀疑这就是为什么异常会被神秘地丢失。

值得注意的是,如果套接字在被调用时处置,BeginReceiveBeginSend都可以直接抛出。

答案 1 :(得分:0)

  

如果套接字恰好在Socket.BeginSend方法之前关闭   被叫(即有人通过网络电缆或服务器上的电话)   另一端崩溃)

我不明白。这些事件都不会关闭你的套接字。只有你可以关闭你的插座。这些事件可以中止连接,在这种情况下,您的发送将获得ECONNRESET在C#中映射到的任何异常。如果您自己关闭套接字然后发送,那么如果C#中没有其他内容可以先将其捕获,您将获得EBADF映射到的任何内容。