2010-10-07 29 views
5

Làm cách nào để tạo ổ cắm UDP của máy khách trong C++ để nó có thể nghe trên cổng đang được ứng dụng khác lắng nghe? Nói cách khác, làm thế nào tôi có thể áp dụng ghép kênh trong C++?Ghép kênh cổng C++ UDP

+0

Tại sao bạn làm điều đó? – jweyrich

+0

Ghép kênh chỉ hữu ích nếu đầu kia của ổ cắm đang mong đợi dữ liệu được kết hợp (trừ khi bạn đang cố gắng "giả mạo" dữ liệu mà đầu kia mong đợi). – dreamlax

+0

Tôi đoán tôi phải giải thích kịch bản tốt hơn một chút. Tôi có một ứng dụng đang chạy trên cổng 5000. Tôi muốn nghe trên cùng một cổng, để tôi có thể nhận và phân tích tất cả các gói mà ứng dụng đang nhận. Tôi nghĩ rằng tôi có thể sử dụng SO_REUSEADDR tùy chọn để ràng buộc các ổ cắm, nhưng WAITS này cho các ứng dụng ban đầu để đóng trước khi chương trình của tôi nhận được các gói tin trên cùng một cổng. Tôi hy vọng câu hỏi và hành vi mong muốn là rõ ràng ngay bây giờ. Cảm ơn vì đã trả lời. – SkypeMeSM

Trả lời

3

Tôi muốn nghe trên chỉ có một cổng

Bạn có thể làm điều đó với một sniffer. Chỉ cần bỏ qua các gói tin từ các cổng khác nhau.

tôi có thể cần để ngăn chặn nó từ việc gửi một số gói đặc biệt, bởi vì chương trình của tôi sẽ gửi nó thay cho ứng dụng ban đầu

Được rồi, ở đây tôi đề nghị bạn để loại bỏ sniffers, và sử dụng một MITM kỹ thuật.

Bạn cần phải dựa vào quy tắc tường lửa PREROUTING để chuyển hướng các gói tới ứng dụng "proxy". Giả sử UDP, Linux iptables, và "Proxy" chạy trên cùng một máy chủ, đây là những gì các "Proxy" thực sự cần phải làm:

1. Thêm quy tắc tường lửa để divert sự các gói dữ liệu (làm điều đó bằng tay, nếu bạn thích):

iptables -t nat -A PREROUTING -i <iface> -p <proto> --dport <dport> 
    -j REDIRECT --to-port <newport> 

2. Bind và nghe trên <newport>.

3. Rơ le tất cả lưu lượng truy cập giữa 2 điểm cuối (máy khách và đích ban đầu).Nếu bạn đang chạy "proxy" trên một máy chủ lưu trữ khác, hãy sử dụng getsockopt với SO_ORIGINAL_DST để truy xuất địa chỉ đích ban đầu.

Nghe có vẻ phức tạp, nhưng ... vâng, đó là vì nó hơi phức tạp :-) Tham khảo tài liệu tường lửa của bạn nếu giả định của tôi phân biệt.

+0

Tôi đoán đây chính xác là những gì tôi cần. :) Cảm ơn rất nhiều. – SkypeMeSM

1

Đây là không ghép - thuật ngữ được dành riêng cho việc xử lý I/O trên nhiều kênh khác nhau trong quá trình tương tự và nơi mà mọi thứ như select(2)poll(2) là hữu ích nhất.

Những gì bạn đang yêu cầu là multicast. Here là ví dụ cơ bản.

Lưu ý rằng IP có một dải địa chỉ đặc biệt (nhóm a.k.a.) để phát đa hướng. Chúng được ánh xạ tới các địa chỉ ethernet đặc biệt. Người nghe sẽ phải tham gia nhóm đa hướng, trong khi người gửi không phải làm như vậy, nó sẽ gửi như bình thường.

Hy vọng điều này sẽ hữu ích.

+0

Tôi có một ứng dụng phần mềm chạy trên cổng 5000 và tôi không thể sửa đổi ứng dụng đó để nó tham gia bất kỳ nhóm phát đa hướng nào hoặc tương tự như vậy. Tôi muốn nghe trên cùng một cổng để mã của tôi có thể phân tích cú pháp tất cả các gói nhận được bởi ứng dụng đó. Tôi đã có một khái niệm rằng điều này được gọi là 'ghép kênh', nhưng tôi không thể tìm thấy một ví dụ thích hợp cho cùng. – SkypeMeSM

+0

Sau đó lấy Wireshark (http://www.wireshark.org/), đánh các gói dữ liệu, đổ vào một tập tin, và đi vào nó. –

+0

Tôi đang sử dụng wireshark để xem các gói ngoại tuyến, nhưng tôi phải viết một chương trình C++ có khả năng ngửi hoặc nghe trên một cổng cụ thể chứ không phải trên tất cả các cổng và không thể ngoại tuyến được. Tôi có thể sử dụng thư viện libpcap, nhưng như tôi đã nói tôi muốn nghe chỉ trên một cổng, và tôi có thể cần dừng nó gửi một số gói tin cụ thể, vì chương trình của tôi sẽ gửi nó thay vì ứng dụng gốc !! Tôi không chắc liệu tôi có làm bạn bối rối không :) – SkypeMeSM

2

Đây chỉ là gói sniffing như tcpdump hoặc snoop, mở ổ cắm thô và kéo mọi thứ từ dây và bộ lọc theo yêu cầu của bạn. Có thể bạn sẽ muốn sử dụng libpcap để làm mọi việc dễ dàng hơn một chút.

Không có đặc quyền của quản trị viên hoặc người dùng siêu, bạn sẽ cần ứng dụng đích để mở cổng với SO_REUSEADDRSO_REUSEPORT khi thích hợp cho nền tảng. Thông báo trước là bạn chỉ có thể nhận các gói broadcast và multicast, các gói unicast được gửi tới socket mở đầu tiên.

+0

Ok. Vì vậy, theo ý kiến ​​của bạn, lựa chọn duy nhất khác là sử dụng libpcap để sniff mỗi gói trên một giao diện mạng và sau đó lọc ra các gói tin cho cổng cụ thể đó. Tôi đã nghĩ rằng vì đây là những gói UDP (kết nối ít), nó không phải là một vấn đề để thụ động/chủ động gửi/nhận gói tin trên cùng một cổng. – SkypeMeSM

+0

Tôi đã thử, Linux chỉ gửi đến ổ cắm đầu tiên, nó không ghép các gói unicast. Các nền tảng khác có thể nhưng không có khả năng khác nhau vì lý do hiệu suất. –

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