1. 程式人生 > >C#中Socket.Receive()的超時問題

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

相關推薦

C#Socket.Receive()的超時問題

最近在除錯程式的時候,希望1秒鐘呼叫一次 Socket.Receive() 來接收資料。 實際上,應該是說,如果沒有資料到來,就是1秒鐘一次,如果有資料到來,則收到資料後立即繼續接收,然後繼續是1秒鐘接收一次。 C#的相關程式碼如下: public boo

C++Socket程式設計入門

C++中Socket程式設計入門 轉載 :http://www.cnblogs.com/L-hq815/archive/2012/07/09/2583043.html 該作者也是轉載,為國外網站翻譯之作 本人在學習Socket程式設計時,在其他地方看到了不錯Socket入門文件,通俗

C語言socket設定超時的幾種方法

1.建立socket2.將該socket設定為非阻塞模式3.呼叫connect()4.使用select()檢查該socket描述符是否可寫(注意,是可寫)5.根據select()返回的結果判斷connect()結果6.將socket設定為阻塞模式(如果你的程式不需要用阻塞模式

C#帶連線超時功能的TcpClient類

關於TcpClient 類在C#中對於操作TCP connection是非常方便的,非常地好! 但是有一點就是,這個類對於CONNECT操作沒有設定超時! 系統預設的是60秒的超時,這明顯過於地長。 我們可以重新去用Thread的join這個帶引數的執行緒

c#關於socket連線超時控制的方案

之前有一個專案用到Remoting技術,當遠端的地址無效或伺服器沒執行時,訪問遠端物件方法,會經過幾十秒的時間才丟擲異常。因為我用的是tcp模式,所以想到可以用socket來測試連線,就可以在呼叫遠端物件方法之前知道遠端服務有沒有執行。程式碼如下: public clas

C#Socket關閉 Close、Dispose、Shutdown、Disconnect

An answer on StackOverflow made me think I have finally reached some glimpse of an understanding. Then I went testing for a bit and her

C#Socket通訊程式設計的非同步實現

本文將在C#中Socket同步通訊的基礎上,分析和研究Socket非同步程式設計的實現方法,目的是深入瞭解Socket程式設計的基本原理,增強對網路遊戲開發相關內容的認識。 什麼是Socket程式設計的非同步是實現 所謂Socket程式設計的非同步實現是指按

C語言socket設定超時/setsockopt函式

//======================= 在Windows下似乎操作比較簡單,直接呼叫winsock2.h和ws2_32.lib程式設計 #include"stdafx.h" #include"stdio.h" #include "winsock2.h" #pragmacomment(lib,

DEV C++Socket網路程式設計

Dev-C++是一個小巧開源的C/C++整合開發環境,對於大部分的Linux函式,都可以在引用標頭檔案後直接呼叫,但開發socket網路程式卻要多做一些工作。 新增 標頭檔案不可以。 新增  #pragma    comment(lib,"ws2_32.lib") 

詳解C#Socket通訊(四):使用雜湊表管理客戶端

public void StartListening() { //獲取本機IP地址 IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName()); HostIP = ipHo

C 設定Socket連線請求的超時

                C#中, 對於Socket的請求,無論是同步還是非同步,都沒有提供超時機制,SendTimeout,ReceiveTimeout均無用..對於需要測試網路是否正常連線的情況下,,超時控制很是有用,  如果伺服器不存在,或是客戶機網路異常,, 在沒有設定超時的情況下,,Socke

C#設定Socket連線請求的超時

C#中, 對於Socket的請求,無論是同步還是非同步,都沒有提供超時機制,SendTimeout,ReceiveTimeout均無用.. 對於需要測試網路是否正常連線的情況下,,超時控制很是有用,  如果伺服器不存在,或是客戶機網路異常,, 在沒有設定超時的情況下,,So

GUN Csocket學習(一)

ipp 區分 如果 raw 文件表 一起 通訊 res 概念   socket是用於通信的工具。   套接字其實是一個廣義上的進程間通信的信道。就像pipe一樣,在GUN環境下socket也被用一個文件表示。不同的socket文件可以用於不同的進程間通信,甚至可以用來在網絡

C#的多線程超時處理實踐

出現問題 可能性 readline col 似的 rms 應用 true 有一個 最近我正在處理C#中關於timeout行為的一些bug。解決方案非常有意思,所以我在這裏分享給廣大博友們。 我要處理的是下面這些情況: 我們做了一個應用程序,程序中有這麽一個模塊,它的功能向

使用C#Socket進行通訊

err comm bind 客戶端 ipaddress odi nac rgs tel class Program { static void Main(string[] args) { Socket serv

C# 使用TCP連線設定超時問題

在使用C#中用TCP連線去掃描IP的過程中,發現,TCP連線沒有可以設定連線超時的方法,如果掃描到空的IP或連線失敗,那要等20多秒,甚至更長, 我們可以重新去用Thread的join這個帶引數的執行緒,來解決這個問題,下面的這個類就是但連線超時引數的TCPCliento類 the TcpC

C#判斷socket是否已斷開的方法

 C#中判斷socket是否已斷開的方法        記得以前Delphi/BCB裡的socket程式設計,要判斷[連線的另一方]是否斷開了,只要在ondisconnect事件裡處理就行了!如今在C#

C++ TCP socket程式設計的小陷阱(服務端accept 不阻塞 和 客戶端connect 重連失敗)

在編寫一個使用C++ socket實現的TCP服務端與客戶端小軟體時接連碰上2個小陷阱, 終歸是實踐不足,基本功不紮實。 第1個問題: 服務端的accept函式沒有阻塞     程式執行到accept這裡時直接就跳了過去,根本沒停下來。     懷疑過socket

C# struct 固定長度(Socket報文頭規範)

[MarshalAs(UnmanagedType.I4)]此屬性標識 int型別 長度為4位元組int有好幾種:Int16 Int32 Int64意義同名,分別佔16位,32位,64位8位一位元組,所以分別佔2位元組,4位元組,8位元組C#對整數做了基元型別:short對映I

使用Csocket收發UDP包,併發送UDP包到syslog

一、UDP相關程式碼在main函式中,先建立了一個執行緒來做UDP伺服器,然後建立socket向UDP伺服器傳送和接收資料,最終直接使用給定的ip和埠號,向搭建好的rsyslog伺服器傳送資料,可以看到資料。為了省事,所有的東西都在一個檔案中寫完了,包括UDP伺服器,UDP客