我有一個用 c 編碼的 udp 時間服務器(用于 linux)。稍后,我會將它安裝在傳感器陣列中,但目前我只是通過在我的客戶端中偵聽 127.0.0.1 來在我的開發機器上對其進行本地測驗。問題是,當我廣播到 INADDR_BROADCAST 時,它不起作用,而如果我明確地將資料報發送到 INADDR_LOOPBACK,那么它就像一個魅力。
這是 UDP 預期的行為嗎?我知道我的大學可能默認關閉所有 udp 埠??,但我還在 StackOverflow 上發現了一個問題,其答案是理論上我本地計算機的資料報實際上應該永遠不會離開。我也找到了這個答案,但我不確定問題是否相似。
我的服務器代碼是:
int main(int argc, char** argv) {
uint16_t broadcast_port = 5070;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in s;
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
printf("Starting time broadcast udp server on port %u\n", broadcast_port);
int broadcastEnable=1;
int ret=setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
memset(&s, '\0', sizeof(struct sockaddr_in));
s.sin_family = AF_INET;
s.sin_port = htons(broadcast_port);
s.sin_addr.s_addr = htonl(INADDR_BROADCAST);
signal(SIGINT, interuptHandler);
uint8_t timesByteArray[sizeof(uint64_t)];
while (goon) {
int flags = 0;
uint64_t ms = time_ms();
orderTimeBytes(ms, timesByteArray);
int b_written = sendto(sockfd, timesByteArray, sizeof(uint64_t), flags, (struct sockaddr *) &s, sizeof(s));
if (b_written < 0) {
perror("Failed to write a datagram");
}
sleep_ns(500000);
}
printf("\nClosing time broadcast udp server\n");
close(sockfd);
return 0;
}
uj5u.com熱心網友回復:
只需在我的客戶端中收聽 127.0.0.1 即可。問題是,當我廣播到 INADDR_BROADCAST 時,它不起作用,而如果我明確地將資料報發送到 INADDR_LOOPBACK,那么它就像一個魅力
TLDR:您的 recv 套接字應該系結到 INADDR_ANY。
您沒有共享您的客戶端代碼,但我相信您的 recv 套接字需要系結到INADDR_ANY(0.0.0.0)。
struct sockaddr_in s = {0}; // zero it all out
s.sin_family = AF_INET;
s.sin_port = htons(broadcast_port);
s.sin_addr.s_addr = htonl(INADDR_ANY); // effectively a no-op since s is already zero'd out.
bind(sock, (sockaddr*)&s, sizeof(s));
真實配接器和環回配接器之間的發送/接收關系因平臺而異——尤其是 Windows 和 Linux。但如果我不得不猜測,當你發送到 255.255.255.255 時,路由表會被查詢并將該地址決議為默認的真實配接器和 IP 地址。該堆疊不一定發夾回在環回配接器上顯式偵聽的套接字。
我記得當偵聽套接字正在偵聽 INADDR_ANY 時,發送到 127.0.0.1 確實有效。所以我猜廣播流量會有類似的行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/537437.html
標籤:CLinuxUDP
下一篇:如何修復此分段錯誤?
