如何从多个端口接收UDP数据?

时间:2016-12-12 06:19:33

标签: c++ sockets networking

我有4个端口 我想等到每个端口收到第一个数据包 我尝试使用select,但是,一旦我从1个端口接收数据,我只能从该端口接收。
我怎么能等到收到所有4个端口? 以下是我对服务器的简单测试实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>

using namespace std;

#define  BUFF_SIZE   1024

struct Programs
{
    int sockfd;
    struct sockaddr_in my_addr;
    char buffer[BUFF_SIZE];
    int port_num;
    int pid;
};

int   main( void)
{
    Programs programs[4];

    struct sockaddr_in their_addr;
    socklen_t addr_len = sizeof(their_addr);
    memset(&their_addr, 0, sizeof(their_addr));

    int maxServerHandle = 0;
    fd_set socks;
    FD_ZERO(&socks);

    int numRecv = 0;

    for(int idx = 0 ; idx < 4 ; idx++){
        memset(&programs[idx].my_addr, 0, sizeof(&programs[idx].my_addr));
        programs[idx].sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        programs[idx].my_addr.sin_family = AF_INET;
        programs[idx].my_addr.sin_port = htons(0);
        programs[idx].my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        if (programs[idx].sockfd < 0 
                || bind(programs[idx].sockfd, (struct sockaddr *)&(programs[idx].my_addr), sizeof(struct sockaddr)))
        {
            cout << "network error" << endl;
            exit(1);
        }

        getsockname(programs[idx].sockfd, (struct sockaddr *)&their_addr, &addr_len);
        programs[idx].port_num = ntohs(their_addr.sin_port);
        cout << "PORTNUM: " << programs[idx].port_num << endl;

        if( programs[idx].sockfd > maxServerHandle){
            maxServerHandle = programs[idx].sockfd;
        }

        FD_SET(programs[idx].sockfd, &socks);
    }

    while(numRecv < 4){
        if (select(maxServerHandle + 1, &socks, (fd_set *)0, (fd_set *)0, 0) >= 0) {
            for (int i = 0; i < 4; i++){
                if (FD_ISSET(programs[i].sockfd, &socks)){
                    recvfrom(programs[i].sockfd, programs[i].buffer, BUFF_SIZE, 0, (struct sockaddr *)&(programs[i].my_addr), (socklen_t *)&addr_len);
                    cout << "receive: " << programs[i].buffer <<  endl;
                    numRecv++;
                }
            }
        }
    }
    cout << " RECV END! " << endl;
    exit(0);
}

0 个答案:

没有答案