C#中Socket.Receive()的超时问题

最近在调试程序的时候,希望1秒钟调用一次 Socket.Receive() 来接收数据。
实际上,应该是说,如果没有数据到来,就是1秒钟一次,如果有数据到来,则收到数据后立即继续接收,然后继续是1秒钟接收一次。

C#的相关代码如下:

public bool ReadDataForMe(Socket sck, uint waitSec)
{
    int rlen = 1;
    DateTime ttStart = DateTime.Now;
    //sck.ReceiveTimeout = 5;
    sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, -300);

    while (true)
    {
      try
      {
        PrintLog("start read socket.\n");
        if (BaseTools.GetEclpseTime(ttStart, 0.4) >= waitSec)
        {
          break;
        }

        rlen = sck.Receive(m_bufRecv, 0, 1000, SocketFlags.None);

        if (rlen == 0)
        {
           BaseTools.Sleep(100);
           continue;
        }
        return true;
      }
      catch (IOException)
      {
          // 读取失败,原因:基础 System.Net.Sockets.Socket 被关闭。
          return false;
      }
      catch (SocketException e)
      {
          if (e.ErrorCode == 10060)
              // 超时的时候错误号码是10060
              continue;
          break;
      }
      catch (Exception e)
      {
          break;
      }
    }
return false;
}

// 如下调用
while(true)
{
   if (ReadDataForMe(mySock, 1))
      break;
}

其中BaseTools为一个基本工具库,自己封装的,这里用到了两个功能,一个是Sleep(),用于休息多长时间,另外一个是 GetEclpseTime() 用于获取指定的一个时间到当前时间的秒数,这样用于计算时间差。
另外还有一个函数 PrintLog() 用于在控制台打印字符串,其中添加了时间信息,代码如下:

public static void PrintLog(string s)
{
   Console.WriteLine($"[{ DateTime.Now.ToString("HH:mm:ss.fff")}] {s}");
}

在每一次打印都添加了时间,精确到毫秒,这样方便对照打印时的时间。
测试方法就是连上服务器之后,服务器不发送数据,此客户端一直调用Receive()接口来收取数据。在每一次接收数据之前都加一行打印:start read socket.

以上为测试的环境情况。
下面测试主要是对函数开始的前几行的socket超时设置以及对超时时间的观察。
如上面的代码那样,设置超时时间为 -300,则打印间隔为500ms
如果改成3,则打印间隔为503ms

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值