C# TCP 客户端异步套接字回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/686618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:28:40  来源:igfitidea点击:

TCP client Asynchronous socket callback

c#asynchronoussocketsclient

提问by Ivan Prodanov

Please note the question is about using an asynchronous callback mode only on sockets!

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

I want to build a TCP client that will notify me when a packet is received and when i the socket is being closed,because the feautures that NET offers with beginRecv,endRecv doesn't inform if the connection is still available.

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

My question: Isn't there a way to create a TCP client much like using WinAPI?

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

I mean calling WSAAsyncSelect with a message,when the message is received it calls the function you've called in WSAAsyncSelect and then you can see whether the connection is closed or there's a new packet through the WParams FD_CLOSE FD_READ FD_WRITE.

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

If there isn't.Can't I control my connection and my incoming packets at the same time? I don't want to call BeginRecv EndRecv all the time. -.-

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

Thanks in advance!

提前致谢!

采纳答案by scottm

If you pass a state object which includes a reference to your socket, You'll have access to the socket itself.

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

public class SocketState
{
  public SocketState(Socket s)
  {
    this._socket = s;
  }

   private Socket _socket;
   public Socket Socket
   {
     get{return _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);
}

回答by Erik Funkenbusch

Your question is not really clear. By the tone of your question, it seems like you don't want to do any extra work. You can't do async without some extra work.

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

The best approach is to use the Asynchronous API from Microsoft, using BeginReceive/EndReceive. These will call your callbacks when the socket is closed. However, you cannot easily use the IO Stream support in .NET by doing this, so there is some extra work involved.

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

If you want more control, you have to do more work. That's all there is to it.

如果你想要更多的控制,你必须做更多的工作。这里的所有都是它的。

回答by sfossen

You could also write a simple threaded version to monitor the socket and give you the events and call the callbacks.

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

Server type code

服务器类型代码

Simple Socket code

简单的套接字代码