【问题标题】:.NETCF Async TCP socket graceful shutdown issue.NETCF 异步 TCP 套接字正常关闭问题
【发布时间】:2011-08-04 01:18:17
【问题描述】:

我有一个 TCP 客户端/服务器应用程序通过 ActiveSync 连接与 Windows CE 设备进行通信。客户端和服务器都使用异步套接字(即Socket.Begin*Socket.End* 函数)。当客户端和服务器都在我的桌面上运行时,一切都按预期运行,但是当客户端在通过 ActiveSync 连接的 Windows CE 设备上运行时,我总是在调用 Socket.Shutdown 后在 ReceiveCallback 上得到一个 SocketException(当设备正在启动断开连接)。完整的例外是:

System.Net.Sockets.SocketException: An error message cannot be displayed because an optional resource assembly containing it cannot be found
at System.Net.Sockets.Socket.ReceiveNoCheck()
at ReceiveAsyncRequest.doRequest()
at AsyncRequest.handleRequest()
at WorkerThread.doWork()
at WorkerThread.doWorkI()
at WorkItem.doWork()
at System.Threading.Timer.ring()

如果服务器(在桌面上运行)启动断开连接,一切似乎也正常工作。关于如何避免这种情况,我有一些想法,包括禁止设备启动断开连接并在启动断开连接后忽略所有异常。但是,我想知道为什么会发生这种情况,以及是否有更好的处理方法。

Disconnect 和 ReceiveCallbacks(在服务器和客户端上操作相同)是:

public bool Disconnect(StateObject state)
{
  try{
    if(state.isDisconnecting) return false;

    state.isDisconnecting = true;
    state.sock.Shutdown(SocketShutdown.Both);
    //Wait for sending and receiving to complete, but don't wait more than 10 seconds
    for(int i=0; i<100 && (state.isSending || state.isReceiving); i++){
      System.Threading.Thread.Sleep(100);
    }

    /* Log the disconnect */

    state.sock.Close();

    return true;
  } catch (Exception e){
    /* Log the exception */

    return false;
  }
}

private void ReceiveCallback(IAsyncResult iar)
{
  StateObject state = (StateObject)iar.AsyncState;
  try{
    //handle the new bytes in the buffer.
    int recv = state.sock.EndReceive(iar);

    //Handle the buffer, storing it somewhere and verifying complete messages.

    if(recv > 0){
      //start listening for the next message
      state.sock.BeginReceive(state.recvBuffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
    } else {
      state.isReceiving = false;
      Disconnect(state);
    }
  } catch (Exception e){
    /* Log the exception */
  }
}

//For reference, A StateObject looks kinda like this:
public class StateObject
{
  public const int BUFFER_SIZE = 1024;

  public Socket sock = null;
  public bool isSending = false;
  public bool isReceiving = false;
  public bool isDisconnecting = false;

  public byte[] recvBuffer = new byte[BUFFER_SIZE];
  public byte[] sendBuffer = new byte[BUFFER_SIZE];

  //Other stuff that helps handle the buffers and ensure complete messages,
  //  even when TCP breaks up packets.
}

【问题讨论】:

  • 永远不要假设 CF 和完整框架的行为相同。 blog.opennetcf.com/ctacke/2008/10/02/…
  • @ctacke,是的,我真的开始想明白了,虽然很痛苦......
  • 调试时是否遇到异常? (是否有 WinCE 的远程调试器?)还有更详细的 InnerException 吗?

标签: c# compact-framework activesync asyncsocket


【解决方案1】:

为了得到实际的异常,可能会尝试找出它需要哪个库并部署它?

【讨论】:

    【解决方案2】:

    如果您的设备上未显示消息,因为您的设备上未安装该消息。您必须安装 netcf.messages.cab。你会在这里找到它:

    C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\Diagnostics
    

    安装此 CAB 文件后,再次运行您的应用程序并发布您收到的新错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多