当我从特定主机接收数据时,我正试图中止向特定主机发送UDP数据。
到目前为止,我已经尝试在其他发送数据的函数中创建一个线程。
线程应该在套接字描述符上检查传入数据最多100秒。
但是select()函数仅等待超时,并且在接收到数据时不响应。套接字已经在调用函数中创建,这里我仅传递文件描述符。
这也是Beej的《网络编程指南》中的修改代码段。
void *bot_listen(void *arg){
printf("Thread starting\n");
size_socks *sock_size=(size_socks*)arg;
int n, rv;
fd_set readfds;
struct timeval tv;
thr_running=1;
FD_ZERO(&readfds);
for(int i=0;i<sock_size->size;i++) {
FD_SET(sock_size->sockets[i], &readfds);
}
n = sock_size->size + 1;
tv.tv_usec = 0;
tv.tv_sec = 100;
rv = select(n, &readfds, NULL, NULL, &tv);
if (rv == -1) {
perror("select"); // error occurred in select()
} else if (rv == 0) {
printf("Timeout occurred! No data after 100 seconds.\n");
} else {
bot_recv_message=1;
}
thr_running=0;
}
void send_dgrams(int num_ip, struct message ip_port_pairs, char *message){
struct addrinfo hints, *res;
struct sockaddr_in *dest;
char udp_ip[INET_ADDRSTRLEN];
char str[INET6_ADDRSTRLEN];
char udp_port[22];
char *p;
int *sockfd, time_elapsed=0;
size_socks ss;
printf("Message, beginning of send_dgrams: %s\n", message);
pthread_t listen_thread;
sockfd = (int*)malloc(sizeof(int)*num_ip);
dest = malloc(sizeof(struct sockaddr_in)*num_ip);
p=&(ip_port_pairs.command);
p++;
for(int i =0; i<num_ip;i++) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
strcpy(udp_ip, p);
p+=INET_ADDRSTRLEN;
strcpy(udp_port,p);
p+=22;
getaddrinfo(udp_ip, udp_port, &hints, &res);
sockfd[i] = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
dest[i].sin_family = res->ai_family;
dest[i].sin_port = ((struct sockaddr_in *) res->ai_addr)->sin_port;
dest[i].sin_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
memset(dest[i].sin_zero, '\0', sizeof(dest[i].sin_zero));
}
ss.size=num_ip;
ss.sockets=sockfd;
pthread_create(&listen_thread, NULL, bot_listen, (void*)&ss);
while(bot_recv_message==0 && time_elapsed<100) {
for (int i = 0; i < num_ip; i++) {
printf("Sending this message: %s to socket %d\n", message, sockfd[i]);
inet_ntop(AF_INET, &(dest[i].sin_addr), str, INET_ADDRSTRLEN);
printf("Sending to this address: %s\n", str);
printf("Sending to this port: %d\n", ntohs(dest[i].sin_port));
printf("Did bot receive message? :%d\n", bot_recv_message);
sendto(sockfd[i], message, strlen(message) + 1, 0, (struct sockaddr *) &dest[i], sizeof(dest[i]));
}
sleep(1);
time_elapsed+=1;
}
for(int i=0;i<num_ip;i++){
close(sockfd[i]);
}
bot_recv_message=0;
}
答案 0 :(得分:0)
这可能是问题所在
n = sock_size->size + 1;
...
rv = select(n, &readfds, NULL, NULL, &tv);
select()
的第一个参数的值不够大。
select()
的手册页中关于第一个参数的内容如下:
nfds
应该设置为以下任意一个中编号最高的文件描述符 这三个集合加1。每个集合中指示的文件描述符 进行检查,直到达到此限制(但请参阅BUGS)。
所以尝试这样的事情:
int max_fd = -1;
for(int i=0;i<sock_size->size;i++) {
FD_SET(sock_size->sockets[i], &readfds);
if (sock_size->sockets[i] > max_fd)
max_fd = sock_size->sockets[i];
}
...
rv = select(max_fd + 1, &readfds, NULL, NULL, &tv);