2012-02-11 25 views
6

Có thể nhận dữ liệu từ nhiều nhóm phát đa hướng trên một socket không?Đăng ký nhiều nhóm đa hướng trên một ổ cắm (Linux, C)

Ví dụ:

void AddGroup(int sock, 
       const char* mc_addr_str, 
       int mc_port, 
       const char* interface) { 
    struct sockaddr_in mc_addr; 
    memset(&mc_addr, 0, sizeof(mc_addr)); 
    mc_addr.sin_family  = AF_INET; 
    mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str); 
    mc_addr.sin_port  = htons(mc_port); 

    if ((bind(sock, (struct sockaddr *) &mc_addr, 
      sizeof(mc_addr))) < 0) { 
    perror("bind() failed"); 
    exit(1); 
    } 

    // construct an IGMP join request structure 
    struct ip_mreq mc_req; 
    mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str); 
    mc_req.imr_interface.s_addr = inet_addr(interface); 

    if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
        (void*) &mc_req, sizeof(mc_req))) < 0) { 
    perror("setsockopt() failed"); 
    exit(1); 
    } 
} 

Mã này hoạt động khi tôi thêm một nhóm multicast. Nhưng khi tôi cố gắng thêm cái khác, "ràng buộc" không thành công. Tôi không hoàn toàn hiểu tại sao ràng buộc cần phải có ở nơi đầu tiên? (nhưng mã không hoạt động nếu không có nó).

Lý tưởng nhất là tôi muốn gọi AddGroup nhiều lần trên cùng một ổ cắm. Điều này có thể không? Hay tôi cần một ổ cắm cho mỗi nhóm và sau đó chỉ cần sử dụng bỏ phiếu?

Trả lời

3

Bạn chỉ liên kết một ổ cắm một lần. Bỏ qua các ràng buộc lần thứ hai và xem những gì sẽ xảy ra.

-3

Tôi không tin rằng có thể tham gia nhiều hơn một nhóm phát đa hướng trên một ổ cắm đã cho. Ổ cắm được xác định bằng cách ghép đôi cổng ip/port nguồn và cổng ip đích. Hệ điều hành sẽ không biết phải làm gì với dữ liệu đi xuống từ ip/port thứ hai vì nó sẽ không có một ổ cắm để gửi nó đến.

Ràng buộc là cần thiết để đăng ký kết nối với hệ điều hành. Về cơ bản nó giống như đăng ký một tập tin xử lý.

Cách tốt nhất để làm điều này là tạo một ổ cắm cho mỗi nhóm phát đa hướng và sau đó gọi select(). select() sẽ thông báo cho bạn nếu bất kỳ ổ cắm nào có sẵn dữ liệu để đọc.

Kiểm tra trang người dùng của bạn để biết thêm thông tin về socket(), bind() và chọn().

+2

Bạn đang không chính xác. Bạn có thể tham gia bao nhiêu nhóm tùy thích. Tham gia các nhóm phát đa hướng không liên quan gì đến bộ nhận dạng. – EJP

6

Bạn có thể tham gia bao nhiêu nhóm đa hướng tùy thích, sử dụng cuộc gọi setsockopt() thích hợp với tùy chọn IP_ADD_MEMBERSHIP, thay vì liên kết().

+0

Khi tôi xóa "liên kết" trong các cuộc gọi tiếp theo thành AddGroup, chỉ nhóm phát đa hướng đầu tiên dường như được "đăng ký". – Switch

+0

@Switch Nếu một nhóm không thể truy cập thông qua tuyến đường IP mặc định của bạn, bạn cần chỉ định địa chỉ địa phương đi thích hợp khi tham gia nhóm, vì vậy thông báo IGMP thêm thành viên sẽ đi theo hướng thích hợp. – EJP

2

bind đến địa chỉ thụ động, tức là 0.0.0.0 cho IPv4 và sử dụng ASM hoặc SSM để kéo các nhóm bổ sung, ví dụ: IP_ADD_MEMBERSHIP như được liệt kê.

Bạn chỉ có thể bind một lần.

2

Bạn có thể tham gia bao nhiêu nhóm đa hướng bạn muốn trên một ổ cắm. Xem setsockopt(), IP_PKTINFO để biết cách nhận dạng nhóm multicast nào bạn đang đọc dữ liệu.

0

Vâng, nó có thể: nhìn ví dụ trong liên kết (http://www.tenouk.com/Module41c.html) Để rút ngắn này lên trong một vài bước sau:

  1. Bạn setsockopt với SO_REUSEADDR
  2. Bạn buộc ở dưới INADDR_ANY
  3. Bạn setsockopt với IP_ADD_MEMBERSHIP trên mỗi nhóm bạn muốn nhận datagram từ.
  4. Dường như với tôi rằng việc sử dụng IP_PKTINFO đưa ra một lựa chọn để phân biệt các gói tin nhận được, nhưng người gửi phải chăm sóc về việc chuẩn bị cho họ (Setting the source IP for a UDP socket)
Các vấn đề liên quan