poll()函数始终返回零

问题描述 投票:0回答:1

我已经坚持了几天。我的代码编译没有问题,但是poll()函数始终返回零值。这导致我的代码没有执行所需的操作。这当然不是最好的代码(我对TCP编程不是很熟悉),并且我的代码中可能存在错误(显然),甚至是大错误。正如我所说的,我已经审查了自己的代码几天了,所以我可能忽略了这些错误。任何提示,评论,帮助都欢迎。有人知道pol()每次返回零的原因吗?

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include "config.h"
#include "connmgr.h"
#include "lib/dplist.h"
#include "lib/tcpsock.h"

//struct pollfd {
            //  int fd;         /* file descriptor */
//              short events;     /* requested events */
  //            short revents;    /* returned events */
    //      };
struct pollfd pollfd_list[MAX_PENDING];
typedef struct {
  sensor_id_t sensor_id;
  time_t last_active;
  tcpsock_t * socket;
}node_t;

void * element_copy(void *);
void element_free(void **);
int element_compare(void *, void *);

dplist_t* sockets;

void connmgr_listen(int port_number){
  FILE * fp = fopen("sensor_data_recv","w");
  sockets = dpl_create(&(element_copy),&(element_free),&(element_compare));
  tcpsock_t * server_sock, * client;
  int server_sd;

  //Creates new socket and the effective pointer to the newly created socket is returned
  //return of function is an integer though
  if (tcp_passive_open(&server_sock,port_number) != TCP_NO_ERROR) {
    exit(EXIT_FAILURE);
  }

  /*A file descriptor is a number that uniquely identifies an open file in a computer's operating system.
  It describes a data resource, and how that resource may be accessed.*/
  if(tcp_get_sd(server_sock,&server_sd) != TCP_NO_ERROR) {
    exit(EXIT_FAILURE);
  }

  //set-up initial listening socket
  node_t * server = malloc(sizeof(node_t));
  server->last_active = time(NULL);
  server->socket = server_sock;
  pollfd_list[0].fd = server_sd;
  pollfd_list[0].events = POLLIN;

  for(int i = 1; i<MAX_PENDING;i++){
    pollfd_list[i].fd = -1;
  }
  sockets = dpl_insert_at_index(sockets,server,0,false);
  printf("size of socket list: %d\n \n",dpl_size(sockets));

  int max_index = 0;
  bool end_server = false;
  while(end_server != true){

      /* The poll() API allows the process to wait for an event to occur and to wake up the process when the event occurs.
      The poll() API might return one of the following values:
                0: Indicates that the process times out.
                -1: Indicates that the process has failed.
                1: Indicates only one descriptor is ready to be processed, which is processed only if it is the listening socket.
                1++: Indicates that multiple descriptors are waiting to be processed.
                    The poll() API allows simultaneous connection with all descriptors in the queue on the listening socket.
      */
      int succes = poll(pollfd_list,max_index+1,TIMEOUT);
      printf("Poll() result: %d\n \n",succes);

       if(pollfd_list[0].revents & POLLIN){
         int i;
         printf("Listening socket\n");
         tcp_wait_for_connection(server_sock,&client);
         node_t * sensor_node = malloc(sizeof(node_t));
         int client_sd;
         sensor_node->socket = client;
         if(tcp_get_sd(client,&client_sd) != TCP_NO_ERROR) {
           exit(EXIT_FAILURE);
         }
         for(i = 1;i < MAX_PENDING;i++){
           if(pollfd_list[i].fd < 0){
             pollfd_list[i].fd = client_sd;
             break;
            }
         }
         pollfd_list[i].events = POLLIN;
         if (i > max_index){
           max_index = i;
         }
         sensor_node->last_active = time(NULL);
         sockets = dpl_insert_at_index(sockets,sensor_node,dpl_size(sockets),true);
         free(sensor_node);
         succes--;
         if(succes <= 0){
           continue;
         }
       }
       node_t * connection = malloc(sizeof(node_t));

       for(int i = 1; i <= max_index; i++){
         if(pollfd_list[i].fd < 0){
           continue;
         }
         connection = dpl_get_element_at_index(sockets,i);
         if(pollfd_list[i].revents & POLLIN){
           printf("Active socket\n");
           sensor_data_t * data = malloc(sizeof(data));
           tcp_receive(connection->socket,&(data->id),(int*)(sizeof(data->id)));
           tcp_receive(connection->socket,&(data->value),(int*)(sizeof(data->value)));
           tcp_receive(connection->socket,&(data->ts),(int*)(sizeof(data->ts)));

           connection->sensor_id = data->id;
           connection->last_active = time(NULL);
           fprintf(fp, "%d %f %ld\n", data->id, data->value, data->ts);
           free(data);
         }
         else if(pollfd_list[i].revents & POLLHUP){
           printf("In if POLLHUP\n");
           tcp_close(&(connection->socket));
           pollfd_list[i].fd = -1;
           pollfd_list[i].events = 0;
           sockets = dpl_remove_at_index(sockets,i,true);
           server->last_active = time(NULL);
           break;
         }

         // TIMEOUT on active connection
         if((connection->last_active + TIMEOUT) < time(NULL) && connection != dpl_get_element_at_index(sockets,0)){

           tcp_close(&(connection->socket));
           sockets = dpl_remove_at_index(sockets,i,true);
           printf("size of list = %d\n",dpl_size(sockets));
           server->last_active = time(NULL);
           break;
         }
       }


       if(dpl_size(sockets)==1 && (server->last_active + TIMEOUT) < time(NULL)){
         printf("In last if\n");
         tcp_close(&(server->socket));
         end_server = true;
       }

       free(connection);
  }
connmgr_free();
printf("Out of while\n");
fclose(fp);
}


void connmgr_free(){
  dpl_free(&sockets,true);
}


void * element_copy(void * src_element)
{
    node_t * copy = malloc(sizeof(node_t));
    *copy = *((node_t*)(src_element));
    return copy;
}

void element_free(void ** element)
{
    node_t * to_remove = *((node_t **)element);
    free(to_remove);
}

int element_compare(void * x, void * y){
  //node_t* sensor_x = (node_t*)x;
    //node_t* sensor_y = (node_t*)y;
    if(x==y){
      return 0;
    }
    else if(x > y){
      return 1;
    }
    return -1;
}


c linux sockets tcp polling
1个回答
0
投票

这里是'timeout'参数的结构:

struct timespec {
           long    tv_sec; /* seconds */
           long    tv_nsec;/* nanoseconds */

发布的代码发送timeout参数的一些编译时间值。这是行不通的。建议:

struct timespec myTimeout;
myTimeout.tv_set = TIMEOUT;
myTimeout.tv_nsec = 0;

...

int succes =
    poll(pollfd_list,max_index+1, myTimeout);

switch( succes )
{
    case -1:
        // handle error
        perror( "poll failed" );
        break;

    case 0:
        // handle timeout
        ...
        break;

    default:
        // handle successful poll
        ...
        break;
}
© www.soinside.com 2019 - 2024. All rights reserved.