2012-04-24 39 views
5

Tôi cần kết nối với hàng nghìn máy khách qua TCP trên giao thức độc quyền để thu thập dữ liệu theo chu kỳ. Tôi cần phải viết một ứng dụng máy chủ .NET trong C#.Bỏ phiếu qua hàng nghìn cổng TCP

Nỗ lực đầu tiên là tạo cho mỗi socket tcp một luồng riêng, hoạt động nhưng cần rất nhiều việc sử dụng CPU.

Tôi phát hiện ra rằng tốt hơn nên sử dụng .NET threadpool. Theo như tôi hiểu (http://msdn.microsoft.com/en-us/library/ms973903.aspx) tôi có thể sử dụng bộ đếm thời gian để có được mỗi ổ cắm có được dữ liệu theo chu kỳ trong một khoảng thời gian nhất định (như 1 giây). Điều này không làm việc cho tôi bởi vì các khe cắm hết thời gian sau khi kết nối được mở ra bởi vì có rất nhiều ổ cắm hơn phải được mở trước khi nó mở các ổ cắm một lần nữa.

Một lần thử khác là sử dụng gọi lại không đồng bộ. Điều này sẽ làm việc cho tôi nhưng tôi không biết làm thế nào để có được các ổ cắm có được dữ liệu cyclically ???

+2

Từ "hàng nghìn" và "chủ đề" không đi đôi với nhau. Hãy thử xem liệu bạn có thể sử dụng từ khóa 'await' để tiếp tục, điều này sẽ cho phép bạn viết mã chống lại các cổng chặn mà không có mã thực sự chặn rất thường xuyên. Đây là loại nguyên tắc đằng sau Erlang và Stackless Python - hai ngôn ngữ được xây dựng đặc biệt cho mạng đồng thời. –

+1

Tại sao bạn phải chu kỳ thông qua các khách hàng để có được dữ liệu? nó sẽ đơn giản hơn (mặc dù đó là tương đối) để chỉ giữ một async đọc được đăng trên mỗi ổ cắm và xử lý dữ liệu khi chúng đến. Nếu bạn thực sự cần đọc theo chu kỳ, bạn có thể trì hoãn đăng lại của một async đọc cho đến khi tất cả các ổ cắm khác đã được phục vụ. –

+1

chỉ cần không thăm dò ý kiến. –

Trả lời

6

Hãy thử sử dụng Socket high performance API cho phép đồng thời nhận dữ liệu trên một số lượng rất lớn các ổ cắm mà không cần sử dụng một luồng trên mỗi socket. Ở cuối bài viết có một liên kết đến một mẫu hoàn chỉnh. Ngoài ra còn có một mẫu trong bài viết MSDN cho SocketAsyncEventArgs class.

+0

API hiệu năng cao của Socket dường như có khả năng xử lý nhiều kết nối đến. Thay vào đó, tôi cần mở các kết nối này. Có thể sử dụng API hiệu suất cao của Socket cho mục đích này không? – sqeez3r

+1

Có, tạo và mở một ổ cắm cho mỗi máy khách, sau đó sử dụng ['Socket.ReceiveAsync()'] (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receiveasync.aspx). –

+1

Tôi đã triển khai nó theo cách này và nó hoạt động rất tốt. Cảm ơn! – sqeez3r

0

Tại sao không điền hàng đợi có địa chỉ bạn cần thăm dò và yêu cầu nhóm của bạn lấy các mục khỏi hàng đợi để xử lý?

Khi bạn đã hoàn thành xong một mục, hãy đẩy nó vào sau hàng đợi.

+3

Đối với một điều, nếu bạn có rất nhiều kết nối không hoạt động, bạn sẽ lãng phí rất nhiều thời gian kiểm tra chúng không có lý do. –

+0

Tôi nghĩ rằng điều này sẽ mất quá nhiều thời gian cho hàng ngàn kết nối. Tôi cần cập nhật từ tất cả các ổ cắm mỗi giây nếu có thể. – sqeez3r