метод опроса() не работает в Linux, но работает в Mac

#c #linux #sockets

Вопрос:

Я использую фрагмент кода C для переадресации портов. Требование состоит в том, чтобы сделать рукопожатие между двумя портами. Это должно быть двустороннее общение. Это означает пересылку всего, что когда-либо происходит на исходном порту, в порт назначения. А затем перенаправить ответ порта назначения на порт источника.

Этот фрагмент кода работает, как и ожидалось, в моей системе mac. Но когда я запускаю этот код в системе Linux, я сталкиваюсь с одной проблемой.

Вопрос:

Код C , который я использую, состоит из 3 частей:

  1. establish_connection_to_source();
  2. open_connection_to_destination();
  3. processconnetion();

В Linux: establish_connection_to_source(); и open_connection_to_destination(); работает отлично. Но processconnetion(); имеет одну проблему.

Ниже приведен способ подключения к процессу:

 void processconnetion()
{
    buffer *todest  = new buffer(socket_list[e_source].fd,socket_list[e_dest].fd);
    buffer *tosrc   = new buffer(socket_list[e_dest].fd,socket_list[e_source].fd);

    if (todest == NULL || tosrc == NULL){
        fprintf(stderr,"out of mememoryn");
        exit(-1);
    }

    unsigned int loopcnt;
    profilecommuncation srcprofile(COMM_BUFSIZE);
    profilecommuncation destprofile(COMM_BUFSIZE);

    while (true) {
        int withevent = poll(socket_list, 2, -1);
        loopcnt  ;
        fprintf(stderr,"loopcnt %d socketswith events = %d source:0x%x dest:0x%xn", loopcnt, withevent, socket_list[e_source].revents, socket_list[e_dest].revents);
        if ((socket_list[e_source].revents | socket_list[e_dest].revents) amp; (POLLHUP | POLLERR)) {
            // one of the connections has a problem or has Hungup
            fprintf(stderr,"socket_list[e_source].revents= 0x%Xn", socket_list[e_source].revents);
            fprintf(stderr,"socket_list[e_dest].revents= 0x%Xn", socket_list[e_dest].revents);
            fprintf(stderr,"POLLHUP= 0x%Xn", POLLHUP);
            fprintf(stderr,"POLLERR= 0x%Xn", POLLERR);
            int resu<
            socklen_t result_len = sizeof(result);
            getsockopt(socket_list[e_dest].fd, SOL_SOCKET, SO_ERROR, amp;result, amp;result_len);
            fprintf(stderr, "result = %dn", result);
            fprintf(stderr,"exiting as one connection had an issuen");
            break;
        }
        if (socket_list[e_source].revents amp; POLLIN) {
            srcprofile.increment_size(todest->copydata());
        }
        if (socket_list[e_dest].revents amp; POLLIN) {
            destprofile.increment_size(tosrc->copydata());
        }
    }
    delete todest;
    delete tosrc;
    close(socket_list[e_source].fd);
    close(socket_list[e_dest].fd);
    srcprofile.dumpseensizes("source");
    destprofile.dumpseensizes("destination");
}
 

Вот он выдает ошибку — exiting as one connection had an issue это значит, что if ((socket_list[e_source].revents | socket_list[e_dest].revents) amp; (POLLHUP | POLLERR)) возвращается true . Проблема связана с портом назначения, а не с источником.

Примечание: Переменные, используемые в processconnetion(); методе: socket_list является структурой типа pollfd . Ниже приводится описание:

 struct pollfd {
    int     fd;
    short   events;
    short   revents;
};

pollfd socket_list[3];


#define     e_source    0
#define     e_dest      1
#define     e_listen    2
 

Ниже приведен вывод на момент выхода:

    connecting to destination:  destination IP / 32001.
   connected...
   loopcnt 1 socketswith events = 1 source:0x0 dest:0x10
   socket_list[e_source].revents= 0x0
   socket_list[e_dest].revents= 0x10
   POLLHUP= 0x10
   POLLERR= 0x8
   result = 0
   exiting as one connection had an issue
 

int withevent = poll(socket_list, 2, -1); здесь возвращаемое значение withevent равно 1

Инициализация списка сокетов:

 guard( (socket_list[e_listen].fd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP )), "Failed to create socket listen, error: %sn", "created listen socket");

 void guard(int n, char *msg, char *success)
{
    if (n < 0) {
        fprintf(stderr, msg, strerror(errno) );
        exit(-1);
    }
    fprintf(stderr,"n = %d %sn",n, success);

}
 

Я не могу разобраться в этой проблеме, так как она отлично работает в mac. Любые зацепки, объясняющие, почему такое поведение в Linux высоко ценится. Заранее спасибо.

Комментарии:

1. Я бы начал с определения того, в каком из соединений возникла проблема и в чем она заключалась.

2. @molbdnilo это с пунктом назначения

3. может быть, это не связано, но loopcnt не инициализировано.

4. И в чем была проблема? Код ошибки? Вы не можете всерьез рассчитывать на помощь, когда опускаете всю полезную информацию.

5. Итак, один из (socket_list[e_source] или socket_list[e_dest] получил ошибку, и вы выбрали только SO_ERROR для одного из них, и он был равен нулю. Так что ты должен принести его для другого, верно? И распечатайте это как SO_ERROR «нет result «, чтобы все знали , о чем вы говорите, включая вас самих. Все это довольно просто.