草庐IT

重用套接字时 C# TCP Socket.Receive 问题

coder 2023-09-18 原文

前言:

我已经被这个困扰了一段时间,但我并没有找到我需要的东西。 我有一个 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

感谢所有阅读本文的人。

此致

克里斯

最佳答案

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

关于重用套接字时 C# TCP Socket.Receive 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8761132/

有关重用套接字时 C# TCP Socket.Receive 问题的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  4. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  5. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  8. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  9. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  10. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

随机推荐