重用socket时C#TCP Socket.Receive问题

时间:2012-01-06 16:34:32

标签: c# .net sockets tcp

序:

我已经被这一段时间困扰了一段时间,并没有太多运气找到我需要的东西。 我有一个C#(.NET 3.5)服务。一个线程充当传入TCP连接的异步侦听器。当数据进入时,我产生了一个新的工作线程来处理数据,然后发回一个确认。

在同一服务中的第二个线程上,我们发送命令,直到今天它将从数据库收集信息,构建新的套接字,连接然后发送命令,我使用Socket.Receive来调用阻塞和等待响应(或直到发生超时)。

一切都运行良好,直到新客户端需要如此快速地(5-10秒间隔)向我们发送数据,以至于我们无法再打开新套接字来获取命令。所以我开始研究何时需要发送“侦听器”线程连接客户端的命令。如果该客户端当前已连接,则使用该套接字而不是创建新套接字。

问题: 我可以将我的命令发送回侦听器接收到的同一个套接字,但是当客户端将数据作为响应发送回来时,Socket.Receive方法需要两次实际触发它认为它接收到的数据。第一次进入我的监听器类,第二次,在我的命令类中,我实际上想要它。

问题: 在调用我的Socket.Receive方法以确保数据到达正确的位置之前,是否有一些选项或我需要做的事情?

在我的监听器类中,我有一个对象列表“CSocketPacket”

public class CSocketPacket
{
   public CSocketPacket(System.Net.Sockets.Socket socket)
   {
      thisSocket = socket;
      this.IpAddress =
          ((System.Net.IPEndPoint)socket.RemoteEndPoint).Address.ToString();
   }

   public System.Net.Sockets.Socket thisSocket;
   public byte[] dataBuffer = new byte[BUFFER_SIZE];
   public string IpAddress; //Use this to search for the socket
}

然后,当我发送命令时,我正在创建一个新的tcp套接字对象:

client = new Socket(
   AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ep = new IPEndPoint(
   IPAddress.Parse(Strings.Trim(ipAddress)), port);
IPEndPoint LocalIp = new IPEndPoint(IPAddress.Parse(
   System.Configuration.ConfigurationManager.AppSettings["SourceIP"]), port);

然后我查看我的监听器类列表以查看该套接字是否已连接:

if (listener.SocketExists(ipAddress)) 
{
   // set the client socket in this class to the 
   // instance of the socket from the listener class
   SocketIndex = listener.FindSocketInList(ipAddress);
   if (SocketIndex != -1)
   {
      // might need to figure out how to avoid copying the socket
      // to a new variable ???
      client = listener.ConnectedSockets[SocketIndex].thisSocket;
      SocketBeingReUsed = true;
   }
}
else
{
   // try to connect to the client
   client.Connect(ep);
}

最后,我完成了发送和接收的步骤

if (client.Connected)
{
   if (client.Poll(1000, SelectMode.SelectWrite))
   {
      int sentAmount = Send(ref client);
      client.ReceiveTimeout = 90000; //90 seconds
      returnData = ReceiveData(ref client, sentAmount);
   }
}

在我调用Socket.Receive(data, total, Socket.ReceiveBufferSize, SocketFlags.None);方法的ReceiveData(ref client,sentAmount)方法中,一切正常。

我一直在使用名为Hercules的工具测试家庭网络中两台机器上的发送/接收数据包。

有没有人对我能做些什么来解决这个问题?我为这么长的问题道歉,但我想尝试提供尽可能多的信息,而不是粘贴我的整个项目。我有任何建议。

免责声明:大约3年前我写了这段代码,所以我很擅长做我不应该做的事情我确定:P

感谢所有阅读此内容的人。

此致

克里斯

1 个答案:

答案 0 :(得分:1)

好的,所以现在我跟着!鉴于你在上面的评论中所说的,那么解决问题的方法是让一个类/线程从套接字读取(这是从套接字读取的正确方法),然后它将协调哪个类获取数据。我认为它可能有点像Command Design Pattern