Tôi mới làm quen với lập trình socket và tôi gặp sự cố khi hiểu cách hoạt động của select()
và FD_SET()
.Làm thế nào để sử dụng lựa chọn và FD_SET trong lập trình socket?
Tôi sửa đổi một ví dụ từ hướng dẫn của Beej để tìm hiểu. Những gì tôi muốn làm trong vòng lặp for là ở mỗi lần lặp lại, tôi đợi trong 4 giây. Nếu đọc có sẵn, tôi sẽ in "Một phím đã được nhấn" và nếu nó hết thời gian chờ, sau đó nó sẽ in "Hết giờ." Sau đó, tôi sẽ xóa các thiết lập và lặp lại quá trình 9 lần. Nhưng có vẻ như một khi bộ mô tả tập tin 0 được thiết lập, nó không bao giờ bị bỏ đặt ngay cả sau khi gọi tới FD_ZERO()
và/hoặc FD_CLR()
. Nói cách khác sau khi tôi nhấn một phím trong vòng lặp đầu tiên của vòng lặp, bộ mô tả tập tin được thiết lập cho phần còn lại của các lần lặp lại và không còn chờ đợi nữa được thực hiện. Vì vậy, phải có một cái gì đó tôi đang mất tích, nhưng tôi không biết những gì.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define SERVERPORT 4950
int main(int argc, char *argv[]) {
struct sockaddr_in their_addr; // connector's address information
struct hostent *he;
int numbytes;
int broadcast = 1;
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
perror("gethostbyname");
exit(1);
}
// this call is what allows broadcast packets to be sent:
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast) == -1) {
perror("setsockopt (SO_BROADCAST)");
exit(1);
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(SERVERPORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
struct timeval tv;
fd_set broadcastfds;
int i;
for(i=0; i < 10; i++) {
tv.tv_sec = 4;
tv.tv_usec = 500000;
FD_ZERO(&broadcastfds);
FD_CLR(0, &broadcastfds);
FD_SET(0, &broadcastfds);
if(select(0+1, &broadcastfds, NULL, NULL, &tv) == -1) perror("select");
if (FD_ISSET(0, &broadcastfds)) printf("A key was pressed!\n");
else printf("Timed out.\n");
fflush(stdout);
}
close(sockfd);
return 0;
}
Nó không phải làm gì cả. Xin lỗi, tôi đã làm một công việc tồi tệ khi xóa các phần không cần thiết cho câu hỏi của tôi. – user1161604