У меня есть следующий код, который просто создает udp socket для прослушивания в группу многоадресной передачи.select() не удается при добавлении флага m32 в Makefile
Я скомпилирую его с помощью gcc, с флагами -c -g, на машине x64. При добавлении -m32 флага ссылки & компиляции фазы в Makefile, выберите() вызова неудача с недопустимым аргументом.
После отладки немного и без флага, я обнаружил, что с помощью флага я получить все то же значение для всех переменных, за исключением:
readfds: 0x80 .. (повторяется 31 раз) - с -m32 флаг
readfds: 0x80 .. (повторяется 15 раз) - без флага
sock.sin_zero: 0x5c, 0xD5, 0xff, и некоторые другие странные значения с -m32 флагом
sock.sin_zero: 0x0,0x0,0x20,0x0,0x0 - без флага
Все переменные чтение выполняется внутри цикла файла, сразу после FD_SET
Я не» (как 32-битная программа предположим, что она работает нормально на 64-битных машинах), или почему select() возвращает Недопустимый аргумент в этом случае.
Может кому-то помочь?
#include <stdio.h>
#include <stdlib.h>
#include <linux/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "radio_listener.h"
int main_loop(int argc, char *argv[])
{
int sock_no = 0;
struct sockaddr_in sock;
socklen_t sock_size;
fd_set readfds;
struct ip_mreq mreq_ip;
uint16_t mreq_port = 0;
char buffer[BUFF_SIZE];
struct timeval timeout_value;
if(VALID_ARGC != argc)
{
fprintf(stderr, "usage: %s <mc_address> <udp_port>\n", argv[0]);
exit(EXIT_FAILURE);
}
mreq_port = atoi(argv[2]);
/* Initialize a socket */
sock_no = socket(AF_INET, SOCK_DGRAM, 0);
if(sock_no < 0)
{
perror("socket() failed!");
exit(1);
}
sock.sin_family = AF_INET;
sock.sin_addr.s_addr = htonl(INADDR_ANY);
sock.sin_port = htons(mreq_port);
sock_size = sizeof(sock);
bind(sock_no, (struct sockaddr *)&sock, sizeof(sock));
/* Initialize the Multicast request */
mreq_ip.imr_multiaddr.s_addr = inet_addr(argv[1]);
mreq_ip.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(sock_no, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq_ip, sizeof(mreq_ip));
while (1)
{
timeout_value.tv_sec = TIMEOUT_VAL;
FD_ZERO(&readfds);
FD_SET(sock_no, &readfds);
int retval = select(sock_no+1, &readfds, NULL, NULL, &timeout_value);
if(-1 == retval)
{
perror("select() failed!");
close(sock);
exit(1);
}
if(0 == retval)
{
printf("Timeout - Closing socket and exiting\n");
break;
}
if(recvfrom(sock_no, buffer, BUFF_SIZE, 0, (struct sockaddr *)&sock, &sock_size) < 0)
{
perror("recvfrom() failed!");
close(sock);
exit(1);
}
printf("%s", buffer);
}
close(sock);
return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
int rc = 0;
rc = main_loop(argc, argv);
return rc;
}
Почему вы используете 'select (sock_no + 1 ...' вместо 'select (sock_no ...'? – ryyker
@ryyker , потому что выбор идет за nfds descriptos (от 0 до nfds -1), в соответствии с: http://www.freebsd.org/cgi/man.cgi?select (см линий 5-6 in ОПИСАНИЕ) – Adiel
Я всегда использовал фактическое значение для сокета в этом аргументе. Не видели «-1». Может быть разница в определении сокетов windows для 'select()' Вы на Linux тогда? Я еще не заметил. – ryyker