2010-02-17 12 views
28

Tôi tự hỏi liệu tôi có thể đặt giá trị thời gian chờ cho phương thức nhận UdpClient hay không.Tôi có thể đặt thời gian chờ cho UdpClient trong C# không?

Tôi muốn sử dụng chế độ chặn, nhưng vì đôi khi udp sẽ mất gói, chương trình của tôi udpClient.receive sẽ treo ở đó mãi mãi.

bất kỳ ý tưởng hay nào về cách tôi có thể quản lý điều đó?

Trả lời

21

Nội dung được đề cập đến được lồng trong ổ cắm UdpClient chứa (UdpClient.Client.ReceiveTimeout).

Bạn cũng có thể sử dụng các phương pháp async để làm điều này, nhưng tay chặn thực hiện:

var timeToWait = TimeSpan.FromSeconds(10); 

var udpClient = new UdpClient(portNumber); 
var asyncResult = udpClient.BeginReceive(null, null); 
asyncResult.AsyncWaitHandle.WaitOne(timeToWait); 
if (asyncResult.IsCompleted) 
{ 
    try 
    { 
     IPEndPoint remoteEP = null; 
     byte[] receivedData = udpClient.EndReceive(asyncResult, ref remoteEP); 
     // EndReceive worked and we have received data and remote endpoint 
    } 
    catch (Exception ex) 
    { 
     // EndReceive failed and we ended up here 
    } 
} 
else 
{ 
    // The operation wasn't completed before the timeout and we're off the hook 
} 
+1

Cảm ơn bạn đã trả lời. – Jack

+0

Đây là một thời gian dài trước đây! Điều đó có vẻ ổn. WaitOne cũng trả về kết quả bạn có thể sử dụng để xác định xem kết quả đã hết thời gian chưa. – weston

2

Có thuộc tính ReceiveTimeout mà bạn có thể sử dụng.

53

Có một SendTimeoutReceiveTimeout tài sản mà bạn có thể sử dụng trong Socket của UdpClient.

Dưới đây là một ví dụ về một thời gian chờ 5 giây:

var udpClient = new UdpClient(); 

udpClient.Client.SendTimeout = 5000; 
udpClient.Client.ReceiveTimeout = 5000; 

... 
+0

Điều này chỉ hoạt động nếu bạn đang thực hiện gửi/nhận đồng bộ. Đối với các cuộc gọi không đồng bộ, bạn có thể sử dụng 'Task.Delay' để tạo thời gian chờ của riêng bạn, ví dụ: 'Task.WhenAny (udpClient.ReceiveAsync(), Task.Delay (5000))'; –

+0

Tất nhiên rồi! Làm thế nào tôi đã bỏ lỡ giải pháp đơn giản đó! Cảm ơn bạn đã bình luận AJ! –

3

Trên thực tế, dường như UdpClient bị phá vỡ khi nói đến timeout. Tôi đã cố gắng để viết một máy chủ với một sợi chỉ chứa một Receive nhận dữ liệu và thêm nó vào một hàng đợi. Tôi đã làm điều này trong nhiều năm với TCP. Kỳ vọng là vòng lặp chặn tại điểm nhận cho đến khi một thông điệp đến từ một người yêu cầu. Tuy nhiên, mặc dù đặt thời gian chờ thành vô cùng:

_server.Client.ReceiveTimeout = 0; //block waiting for connections 
_server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0); 

thời gian chờ sau khoảng 3 phút.

Cách khắc phục duy nhất tôi tìm thấy là bắt ngoại lệ hết thời gian chờ và tiếp tục vòng lặp. Điều này ẩn lỗi Microsoft nhưng không trả lời được câu hỏi cơ bản về lý do tại sao điều này xảy ra.

+1

Tôi đoán có thời gian chờ nội bộ là 200000 ms hoặc lâu hơn? –

1

bạn có thể làm như thế này:

udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);