2015-03-25 32 views
3

我们有接收使用TCP套接字消息的C#服务器。正常流量是调用socket.Accept(),使用socket.BeginReceive()和socket.EndReceive()接收该消息,然后使用socket.Send()来发送响应。这工作正常。C#套接字:接受一个插座,忽略它的消息,发一回

当太多的要求一下子进来,但是,我们要立即拒绝溢出,所以我们没有压倒服务器。在Accept()后直接关闭套接字已经很简单了。但这不允许我们向客户发送有意义的“太忙”消息。

我想什么做的仅仅是调用accept(),然后调用发送(),不接收传入的消息。我试过这个,服务器声称发送我的数据,但我的客户端只收到一个空的响应。我已经尝试使用同步Send()和异步BeginSend()/ EndSend(),但都没有将消息返回给客户端。

是否有可能被接受的套接字上发送一个消息,而无需首先接收传入消息?如果是这样,是否有一件我错过了让它工作?

这里有一个代码片段显示我想要做的事:

 while (!_Done) 
     { 
      Socket socket = null; 
      try 
      { 
       socket = _ListeningSocket.Accept(); 
      } 
      catch (Exception) { } 

      if (socket != null) 
      { 
       if (TooBusy()) 
       { 
        // My new code 
        byte[] send = GetTooBusyResponse(); 
        int ret = socket.Send(send); 
        Console.WriteLine("socket.Send() returned " + ret); 
        socket.Close(); 
        socket = null; 
       } 
       else 
       { 
        // Existing, working code (using custom objects) 
        ClientConnection connection = new ClientConnection(this, socket, !_RequireAuthentication); 
        lock (_ConnectionsToken) 
         _Connections.Add(connection); 
        connection.BeginReceive(); 
       } 
      } 
     } 
+0

你一直在谈论“消息”,但你正在使用TCP套接字。在套接字层面,TCP只是一个*字节流。因此,如果你想*消息*,你必须实现这个概念。换句话说,有* no *保证在一侧的发送调用将与另一侧的接收调用匹配1-1。现在,对于您的实际问题 - 您正在调用['Close'](https://msdn.microsoft.com/en-us/library/wahsac9k(v = vs.110).aspx):“对于面向连接协议,建议您在调用Close方法之前调用Shutdown,这可以确保发送所有数据...“ – 2015-03-25 13:06:27

回答

2

MSDN

Close方法关闭远程主机连接并释放所有 托管和非托管资源与Socket关联。在 关闭时,Connected属性设置为false。

对于面向连接的协议,建议您调用Close方法之前调用 关机。这确保所有数据 在关闭之前在连接的套接字上发送和接收。

如果您需要调用Close,而不首先调用shutdown,你可以 确保数据排队将 设置DontLinger Socket选项设置为false,并指定 非零超时间隔发送发信。关闭将阻塞,直到发送此数据为 或者直到指定的超时到期。如果将DontLinger设置为 false并指定零超时间隔,则Close将释放 连接并自动丢弃传出的排队数据。

因此,要么调用Shutdown第一,或将DontLinger选项设置为false,并设置一个非零超时。

+0

谢谢 - 帮助。 – Laurie 2015-03-26 16:37:07

相关问题