TCP 客户端异步套接字回调

Posted

技术标签:

【中文标题】TCP 客户端异步套接字回调【英文标题】:TCP client Asynchronous socket callback 【发布时间】:2010-10-15 18:09:20 【问题描述】:

请注意,问题是关于仅在套接字上使用异步回调模式

我想构建一个 TCP 客户端,它会在收到数据包以及关闭套接字时通知我,因为 NET 提供的 beginRecv、endRecv 功能不会通知连接是否仍然可用。

我的问题: 有没有办法像使用 WinAPI 一样创建 TCP 客户端?

我的意思是使用消息调用 WSAAsyncSelect,当收到消息时,它会调用您在 WSAAsyncSelect 中调用的函数,然后您可以通过 WParams FD_CLOSE FD_READ FD_WRITE 查看连接是否关闭或有新数据包。

如果没有。我不能同时控制我的连接和传入的数据包吗?我不想一直打电话给 BeginRecv EndRecv。 -.-

提前致谢!

【问题讨论】:

它是否需要异步,或者您可以制作一个线程版本来满足您的需求? 这是客户端还是服务器?你在听还是在连接? 【参考方案1】:

如果您传递一个包含对您的套接字的引用的状态对象,您将可以访问套接字本身。

public class SocketState

  public SocketState(Socket s)
  
    this._socket = s;
  

   private Socket _socket;
   public Socket Socket
   
     getreturn _socket;
   



void SomeFunction()

//do some stuff in your code

SocketState stateObject = new SocketState(mySocket);
mySocket.BeginReceive(buffer, offset, size, flags, CallBack, stateObject);
//do some other stuff


public void CallBack(IAsyncResult result)

  SocketState state = (SocketState)result.AsyncState;
  state.Socket.EndReceive(result);

  //do stuff with your socket.
  if(state.Socket.Available)
    mySocket.BeginReceive(buffer, offset, size, flags, CallBack, state);

【讨论】:

【参考方案2】:

你的问题不是很清楚。从你的问题的语气来看,你似乎不想做任何额外的工作。如果没有一些额外的工作,你就无法进行异步。

最好的方法是使用 Microsoft 的异步 API,即 BeginReceive/EndReceive。这些将在套接字关闭时调用您的回调。但是,您不能通过这样做轻松地使用 .NET 中的 IO 流支持,因此涉及一些额外的工作。

如果你想要更多的控制,你必须做更多的工作。仅此而已。

【讨论】:

@Mystere Man,当我调用 BeginDisconnect 时,它会断开我的连接,而我希望程序在套接字被服务器断开连接时执行回调。我对 BeginRecv,EndRecv 感觉很好,但是如果连接仍然存在,它不会通知我。这就是我如此生气的原因。你能提供一个解决方案 连接存活时不需要通知你,只需要在连接死亡时通知你。 EndReceive 通过返回一个异常或 0 个字节来做到这一点。【参考方案3】:

您还可以编写一个简单的线程版本来监控套接字并为您提供事件并调用回调。

Server type code

Simple Socket code

【讨论】:

以上是关于TCP 客户端异步套接字回调的主要内容,如果未能解决你的问题,请参考以下文章

来自回调 c# 的未处理异常错误

处理异步套接字(.Net)后仍然会调用回调

提升异步 tcp 客户端

使用 Boost Asio 在 TCP 套接字上执行异步写入操作

Socket 服务器数据接收混乱

Swoole 中使用 TCP 异步服务器TCP 协程服务器TCP 同步客户端TCP 协程客户端