C++ 从本地工作中恢复,但不要';在执行之间的随机端口上无法接收任何内容

C++ 从本地工作中恢复,但不要';在执行之间的随机端口上无法接收任何内容,c++,c,multithreading,sockets,recvfrom,C++,C,Multithreading,Sockets,Recvfrom,我正在开发一个多线程UDP侦听器,我陷入了一个绝对超越我的问题 因此,我需要在几个端口接收大量UDP数据包。在本地,对我来说,最好的解决方案是调用非阻塞recvfrom,线程数量与我正在侦听的端口数量相同(select和poll对于我的要求来说太慢)。我使用的是线程池管理器,它只调用线程和队列任务。代码如下: void receiveFromSocket(void * arguments){ sockaddr_in client; // Local socklen_t cli

我正在开发一个多线程UDP侦听器,我陷入了一个绝对超越我的问题

因此,我需要在几个端口接收大量UDP数据包。在本地,对我来说,最好的解决方案是调用非阻塞recvfrom,线程数量与我正在侦听的端口数量相同(select和poll对于我的要求来说太慢)。我使用的是线程池管理器,它只调用线程和队列任务。代码如下:

void receiveFromSocket(void * arguments){

    sockaddr_in client;  // Local
    socklen_t clientSize = sizeof(client);
    memset(&client, 0, sizeof(client));
    struct arg_struct_listenPort *args2 = (struct arg_struct_listenPort *)arguments;
        int fd = args2->arg_fd;
        int port = args2->arg_port;

    for(;;) {
        char buf[158];
        memset(buf,0,158*sizeof(char));
        int n = recvfrom(fd, (char * ) buf, 158, MSG_DONTWAIT, ( struct sockaddr *) &client, &clientSize);

            if(n == -1){
               //cerr << "Error while receiving from client: " << errno << endl;
               continue;
            }

            if(n != 158){
               cerr << "Discarded message since it's not 158 bytes." << endl;
               continue;
            }
            struct arg_struct args;
                args.arg_port = port;
                memcpy(args.buf,buf,158);

            thpool_add_work(globals.thpool, socketThread, (void*)(&args));

    }

}


/// Runs the Socket listener
int network_accept_any()
{
        vector<int>::iterator i;
        for(i = globals.fds.begin(); i != globals.fds.end(); i++){
            int port = distance(globals.fds.begin(),i);
            struct arg_struct_listenPort args;
                args.arg_fd = *i;
                args.arg_port = globals.cmnSystemCatalogs[port].diag_port;
            thpool_add_work(globals.thpool, receiveFromSocket, (void*)(&args));
        }
        cout << "Listening threads created..." << endl;

    return 0;
}
void receiveFromSocket(void*参数){
客户端中的sockaddr_;//本地
socklen_t clientSize=sizeof(客户端);
memset(&client,0,sizeof(client));
struct arg_struct_listenPort*args2=(struct arg_struct_listenPort*)参数;
int fd=args2->arg\u fd;
int端口=args2->arg\u端口;
对于(;;){
char-buf[158];
memset(buf,0158*sizeof(char));
int n=recvfrom(fd,(char*)buf,158,MSG_DONTWAIT,(struct sockaddr*)和clientSize);
如果(n==-1){

//cerr多么令人惊讶的欢迎

@molbdnilo是绝对正确的:


您正在使用指向其生存期已结束的对象的指针(&args)。 这有未定义的行为-它可能看起来有效,但它是一个bug 那需要一个修理工

这是固定的代码。向线程提供参数时要小心

void receiveFromSocket(void * arguments){

    sockaddr_in client;  // Local
    socklen_t clientSize = sizeof(client);
    memset(&client, 0, sizeof(client));
    struct arg_struct_listenPort *args2 = (struct arg_struct_listenPort *)arguments;
        int fd = args2->arg_fd;
        int port = args2->arg_port;

    for(;;) {
        char buf[158];
        memset(buf,0,158*sizeof(char));
        int n = recvfrom(fd, (char * ) buf, 158, MSG_WAITALL, ( struct sockaddr *) &client, &clientSize);

            if(n == -1){
               cerr << "Error while receiving from client: " << errno << endl;
               continue;
            }

            if(n != 158){
               cerr << "Discarded message since it's not 158 bytes." << endl;
               continue;
            }
            arg_struct *args = new arg_struct;
                args->arg_port = port;
                memcpy(args->buf,buf,158);

            thpool_add_work(globals.thpool, socketThread, (void*)(args));

    }

}


/// Runs the Socket listener
int network_accept_any()
{
        vector<int>::iterator i;
        for(i = globals.fds.begin(); i != globals.fds.end(); i++){
            int port = distance(globals.fds.begin(),i);
          arg_struct_listenPort *args = new arg_struct_listenPort;
                args->arg_fd = *i;
                args->arg_port = globals.cmnSystemCatalogs[port].diag_port;
            thpool_add_work(globals.thpool, receiveFromSocket, (void*)(args));
        }
        cout << "Listening threads created..." << endl;


    return 0;
}
void receiveFromSocket(void*参数){
客户端中的sockaddr_;//本地
socklen_t clientSize=sizeof(客户端);
memset(&client,0,sizeof(client));
struct arg_struct_listenPort*args2=(struct arg_struct_listenPort*)参数;
int fd=args2->arg\u fd;
int端口=args2->arg\u端口;
对于(;;){
char-buf[158];
memset(buf,0158*sizeof(char));
int n=recvfrom(fd,(char*)buf,158,MSG_WAITALL,(struct sockaddr*)和clientSize);
如果(n==-1){

cerr语言注释:通过IP网络的数据单元称为“数据包”,而不是“数据包”。如果您将尽可能多的线程用于该任务,那么执行非阻塞I/O在最好的情况下似乎是无用的。在最坏的情况下,这可能会导致您的问题,因为您将有很多繁忙的循环。通常,这是多线程和非阻塞I/O之间的选择。此外,每个端口一个线程,池可能会起作用没有什么有用的。在每个端口用一个线程执行阻塞I/O是我将多线程应用于此类任务的方式。谢谢你的评论,John。我理解你的意思。但是我以很高的速度接收数据包,使用阻塞I/O使我多次接收相同的数据包。无论如何,它应该能够接收到相同的数据包每个端口至少有一个数据包,对吗?UDP,顾名思义是不保证的。不管你做什么,你都不能保证发送的数据包会被传递。此外,如果“使用阻塞I/O使我多次接收相同的数据包”,这表明你的代码中有一个bug。默认设置中没有任何固有的缺陷“阻止I/O”最终会复制数据包。您只需调试自己的代码。“您使用的是指向生命周期已结束的对象的指针(
&args
)。这有未定义的行为-它可能看起来有效,但这是一个需要修复的错误。”。
void receiveFromSocket(void * arguments){

    sockaddr_in client;  // Local
    socklen_t clientSize = sizeof(client);
    memset(&client, 0, sizeof(client));
    struct arg_struct_listenPort *args2 = (struct arg_struct_listenPort *)arguments;
        int fd = args2->arg_fd;
        int port = args2->arg_port;

    for(;;) {
        char buf[158];
        memset(buf,0,158*sizeof(char));
        int n = recvfrom(fd, (char * ) buf, 158, MSG_WAITALL, ( struct sockaddr *) &client, &clientSize);

            if(n == -1){
               cerr << "Error while receiving from client: " << errno << endl;
               continue;
            }

            if(n != 158){
               cerr << "Discarded message since it's not 158 bytes." << endl;
               continue;
            }
            arg_struct *args = new arg_struct;
                args->arg_port = port;
                memcpy(args->buf,buf,158);

            thpool_add_work(globals.thpool, socketThread, (void*)(args));

    }

}


/// Runs the Socket listener
int network_accept_any()
{
        vector<int>::iterator i;
        for(i = globals.fds.begin(); i != globals.fds.end(); i++){
            int port = distance(globals.fds.begin(),i);
          arg_struct_listenPort *args = new arg_struct_listenPort;
                args->arg_fd = *i;
                args->arg_port = globals.cmnSystemCatalogs[port].diag_port;
            thpool_add_work(globals.thpool, receiveFromSocket, (void*)(args));
        }
        cout << "Listening threads created..." << endl;


    return 0;
}