Программирование сокета C: клиент send (), но сервер select () не видит его - PullRequest
1 голос
/ 17 апреля 2010

У меня есть сервер и клиент, работающий на двух разных машинах, где клиент send() s, но сервер, похоже, не получает сообщение. Сервер использует select() для мониторинга сокетов для любых входящих соединений / сообщений. Я вижу, что когда сервер принимает новое соединение, он обновляет массив fd_set, но всегда возвращает 0, несмотря на клиентские сообщения send(). Соединением является TCP, а машины разделены одним маршрутизатором, поэтому отбрасывание пакетов маловероятно.

У меня такое ощущение, что проблема не в select(), а, возможно, send() / sendto() от клиента, но я не уверен, как локализовать проблемную область.

    while(1)
{
    readset = info->read_set;   
    ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout);

}

выше - это код на стороне сервера, где на сервере есть поток, который выполняется select() бесконечно.

rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
printf("rv = %i\n", rv);
if (rv < 0)
{
    printf("MAIN: ERROR connect() %i:  %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("connected\n");

sleep(3);

char * somemsg = "is this working yet?\0";
rv = send(sockfd, somemsg, sizeof(somemsg), NULL);
if (rv < 0)
    printf("MAIN: ERROR send() %i:  %s\n", errno, strerror(errno));
printf("MAIN: rv is %i\n", rv);
rv = sendto(sockfd, somemsg, sizeof(somemsg), NULL, &server_address, sizeof(server_address));
if (rv < 0)
    printf("MAIN: ERROR sendto() %i:  %s\n", errno, strerror(errno));
printf("MAIN: rv is %i\n", rv);

и это сторона клиента, к которой он подключается, отправляет сообщения и возвращает

connected
MAIN: rv is 4
MAIN: rv is 4

Ответы [ 2 ]

0 голосов
/ 18 апреля 2010

Что-то не так с fd_set readset, а не то, что я считал проблематичным. ПРОПИСЬ qrdl за то, что он привлек мое внимание.

0 голосов
/ 18 апреля 2010

подключен
ГЛАВНАЯ: рв 4
ГЛАВНАЯ: рв 4

Странно, что "rv is 4", особенно учитывая, что сообщение было длиной 22 символа. «4» также имеет тенденцию быть размером указателей в большинстве 32-битных сред. Вы должны взглянуть на то, что sizeof(somemsg) дает вам; я предполагаю, что он дает вам размер указателя (4), а не строки (22).

Где вы обновляете набор для чтения? Насколько я знаю, детали реализации структуры / типа fd_set не являются частью интерфейса сокетов BSD. Это может быть указатель куда-то, насколько вы знаете, и система может удалять сокет вашего клиента из исходного набора в первый раз, когда он не был «готов», и никогда больше не проверять его. Единственный способ безопасного и удобного обновления fd_set - использовать макросы FD_*.

Кстати, вам не нужен конечный \0 в конце строки. Си добавляет это в строковые литералы для вас.

...