关于 c socket broadcast 在 client 会收到两次消息

2020-12-02 13:42:56 +08:00
 zckun

问题是这样: 我写了一个 socket 广播服务,用来发送消息给整个内网,内网有多个客户端来接收,但我发现客户端会收到两次相同的消息,我看了服务端打印的内容并没有重复

不知道是不是我查找的方式不对,我 google 没有找到这个问题的解答,自己在仔细看代码的时候改了下地址为本机 ip,然后就解决了我所遇到的问题

以下是我自己的猜测:

C socket broadcast 中,addr 如果不是特定某个 ip(如 255.255.255.255 、192.168.188.255 、...),在 client 端将会收到两次相同的消息

猜测是由于 client 端收到了来自本机的消息和内网的消息,所以出现了两次

1662 次点击
所在节点    C++
3 条回复
Wirbelwind
2020-12-02 14:03:57 +08:00
socket 不提供这样的功能 你写的代码有问题
zckun
2020-12-02 14:10:23 +08:00
@Wirbelwind
这是服务端代码
void server() {
if ((this->sock_fd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
errno_abort("craete socket failed.");
}

if (setsockopt(this->sock_fd_, SOL_SOCKET, SO_BROADCAST, &this->true_flag_, sizeof(this->true_flag_)) < 0) {
errno_abort("set socket opt failed.");
}

memset(&this->send_addr, 0, sizeof(this->send_addr));
send_addr.sin_family = AF_INET;
send_addr.sin_port = (in_port_t) htons(this->server_port_);
inet_aton(this->address_, &send_addr.sin_addr);

while (this->running_) {

if (this->queue_->size() <= 0) continue;

char buf[this->msg_size_];
auto msg = this->queue_->pop();
int retry = 0;

while (retry < this->max_retry_) {
snprintf(buf, sizeof(buf), "%s", msg->c_str());
if (sendto(this->sock_fd_, buf, strlen(buf) + 1, 0,
(struct sockaddr *) &this->send_addr, sizeof(this->send_addr)) >= 0) {
retry = 0;
break;
}
printf("\033[1;91m message %s send failed, retry(%d).\033[0m\n", msg->c_str(), retry);
retry++;
}

if (retry != 0) {
printf("\033[1;91m message %s send finally failed.\033[0m\n", msg->c_str());
}

// 200 毫秒
usleep(10000000 / 5);
}
}
zckun
2020-12-02 14:45:34 +08:00
找到原因了,两张网卡的原因

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/731341

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX