2013-05-02 42 views
5

Tôi xây dựng một ứng dụng đơn giản bằng cách sử dụng c sử dụng recvmmsg() và thông số thứ năm được thông qua là hết thời gian là type struct timespec. Tôi thiết lập thời gian chờ đến 5 giây, nhưng nó không hoạt động, nó sẽ chặn vô cùng.Cách đặt thời gian chờ trong recvmmsg()?

Mã này là như sau:

struct timespec timeout; 

timeout.tv_sec = 5; 
timeout.tv_nsec = 0; 

result = recvmmsg(fd, datagrams, BATCH_SIZE, 0, &timeout); 
+1

Có đề xuất về một lỗi có thể xảy ra ở đây có thể có liên quan: http://lists.openwall.net/netdev/2012/12/23/30 – Vicky

+0

@Vicky: điều đó đúng - tương tự như liên kết trong câu trả lời. Tuy nhiên không rõ ai sẽ thay đổi hành vi - nhiều khả năng nó sẽ bị coi là lỗi tài liệu, trang người dùng sẽ được cập nhật và thông số hết thời gian chờ gần như vô dụng sẽ không được hầu hết các ứng dụng sử dụng. –

+0

có một giải pháp khác trong liên kết tha ở trên sử dụng select: http://stackoverflow.com/questions/12713438/how-to-add-delay-to-sento-and-recvfrom-in-udp-client-server-in- c – MOHAMED

Trả lời

4

Thay vào đó, bạn có thể sử dụng tùy chọn setsockopt với SO_RCVTIMEO để đặt thời gian chờ ổ cắm. Điều này sẽ ảnh hưởng đến tất cả các hoạt động đọc được thực hiện trên đó.

5

Xem ở đây: http://permalink.gmane.org/gmane.linux.man/3440

Về cơ bản các thông số thời gian chờ quy định cụ thể một số tiền tối đa thời gian để chờ đợi cho các tin nhắn nhiều hơn, nhưng các hoạt động cơ bản nhận vẫn được chặn . Vì vậy, nếu bạn đặt thời gian chờ là 5 giây và nhận được một tin nhắn mỗi giây, nó sẽ dừng sau khi nhận (khoảng) 5 tin nhắn ngay cả khi có không gian trong bộ đệm để biết thêm. Những gì nó sẽ không làm là trở lại sau 5 giây nếu không có dữ liệu nào cả. Đối với điều đó, bạn nên sử dụng một trong các cơ chế thông thường, như select() hoặc epoll() với thời gian chờ hoặc chờ đợi, v.v.

+0

Tôi thực sự không thể tưởng tượng một usecase nơi này là hữu ích và dự định. – PlasmaHH

+0

Từ liên kết của câu trả lời này, tôi thấy một trích dẫn rất minh họa "recvmmsg() có tham số timeout rõ ràng nhưng không giống như nó hoạt động đúng và tài liệu không đề cập đến cách nó tương tác với SO_RCVTIMEO. " Điều này rất hữu ích vì nó giải thích tại sao bạn PHẢI thiết lập tham số 'SO_RCVTIMEO' của socket nếu bạn muốn tham số timeout' recvmmsg() 'không chặn vô thời hạn. (Mã kiểm tra recvmmsg của tôi (từ 'man recvmmsg') chặn vô thời hạn với thời gian chờ là 1 giây. Nếu bạn đặt SO_RCVTIMEO của socket, thì nó không chặn vô thời hạn.) –

0

Có lỗi trong việc thực hiện recvmmsg:

Thông báo, pselect cho phép bạn kiểm tra xem dữ liệu có sẵn. Tuy nhiên, nó không đảm bảo recvmmsg sẽ không chờ đợi mãi mãi. Do đó, không sử dụng phương pháp này.

Tôi đề nghị bạn sử dụng SO_RCVTIMEO để thêm tham số timeout của recvmmsg. recvmmsg sẽ thoát nếu không nhận được dữ liệu nào kể từ SO_RCVTIMEO hoặc sau timeout. Trong trường hợp xấu nhất, recvmmsg sẽ thoát sau timeout + SO_RCVTIMEO (trường hợp dữ liệu được nhận ngay trước khi kết thúc timeout và không có dữ liệu nào đến nữa).

Các vấn đề liên quan