测试代码:
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iomanip>
#define BROADCAST_PORT 3956 // GigE Vision discovery port
#define BUFFER_SIZE 1024
int main() {
int sock;
struct sockaddr_in broadcastAddr;
char broadcastBuffer[BUFFER_SIZE];
int broadcastPermission;
unsigned int sendLen;
// 创建UDP套接字
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0) {
std::cerr << "Socket creation failed." << std::endl;
return -1;
}
// 设置广播权限
broadcastPermission = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission, sizeof(broadcastPermission)) < 0) {
std::cerr << "Setting socket option to SO_BROADCAST failed." << std::endl;
close(sock);
return -1;
}
// 设置广播地址
memset(&broadcastAddr, 0, sizeof(broadcastAddr));
broadcastAddr.sin_family = AF_INET;
broadcastAddr.sin_addr.s_addr = inet_addr("255.255.255.255"); // 广播地址
broadcastAddr.sin_port = htons(BROADCAST_PORT);
// 构造广播消息(这里简化了,实际应该按照GigE Vision协议构造)
uint8_t discovery_msg[8] = {0};
discovery_msg[0] = 0x42;
discovery_msg[1] = 0x80;
discovery_msg[2] = 0;
discovery_msg[3] = 0x02; // DISCOVERY_CMD: 0x0002
discovery_msg[4] = 0;
discovery_msg[5] = 0; // length 0
discovery_msg[6] = 0;
discovery_msg[7] = 1; // req_id 1
const size_t send_len = 8;
// 发送广播消息
if (sendto(sock, discovery_msg, send_len, 0, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)) != send_len) {
std::cerr << "Broadcast sendto() failed." << std::endl;
close(sock);
return -1;
}
std::cout << "Broadcast message sent. Waiting for responses..." << std::endl;
// 接收响应(这里简化了,实际应该处理多个响应,并解析GigE Vision协议数据)
struct sockaddr_in recvAddr;
socklen_t addrLen = sizeof(recvAddr);
int recvLen = recvfrom(sock, broadcastBuffer, BUFFER_SIZE, 0, (struct sockaddr *) &recvAddr, &addrLen);
if (recvLen > 0) {
broadcastBuffer[recvLen] = '\0';
std::cout << "Received a response from: " << inet_ntoa(recvAddr.sin_addr) << std::endl;
std::cout << "Size: " << recvLen << std::endl;
std::cout << "Response: " << std::hex << std::setfill('0') << std::setw(2) << std::showbase;
for (int i = 0; i < recvLen; ++i) {
if (i >= 80 && broadcastBuffer[i] > 32 && broadcastBuffer[i] < 127) {
std::cout << broadcastBuffer[i] << " ";
} else {
std::cout << (int)(broadcastBuffer[i]) << " ";
}
if (i > 0 && ((i+1) % 16 == 0)) {
std::cout << std::endl;
}
}
std::cout << std::endl;
char mac[7] = {0};
memcpy(mac, broadcastBuffer + 18, 6);
char ip[4] = {0};
memcpy(ip, broadcastBuffer + 44, 4);
char manufacturer_name[33] = {0};
memcpy(manufacturer_name, broadcastBuffer + 80, 32);
char model_name[33] = {0};
memcpy(model_name, broadcastBuffer + 80 + 32, 32);
char device_version[33] = {0};
memcpy(device_version, broadcastBuffer + 80 + 64, 32);
char manufacturer_spec_info[49] = {0};
memcpy(manufacturer_spec_info, broadcastBuffer + 80 + 96, 48);
char serial_number[17] = {0};
memcpy(serial_number, broadcastBuffer + 80 + 96 + 48, 16);
char user_defined_name[17] = {0};
memcpy(user_defined_name, broadcastBuffer + 80 + 96 + 48 + 16, 16);
std::cout << std::noshowbase << "mac: "
<< (int)(mac[0]) << ":"
<< (int)(mac[1]) << ":"
<< (int)(mac[2]) << ":"
<< (int)(mac[3]) << ":"
<< (int)(mac[4]) << ":"
<< (int)(mac[5]) << std::endl;
std::cout << std::dec << std::setw(0) << "ip: "
<< (int)(ip[0]) << "."
<< (int)(ip[1]) << "."
<< (int)(ip[2]) << "."
<< (int)(ip[3]) << std::endl;
std::cout << "manufacturer_name : " << manufacturer_name << std::endl;
std::cout << "model_name : " << model_name << std::endl;
std::cout << "device_version : " << device_version << std::endl;
std::cout << "manufacturer_spec_info : " << manufacturer_spec_info << std::endl;
std::cout << "serial_number : " << serial_number << std::endl;
std::cout << "user_defined_name : " << user_defined_name << std::endl;
} else {
std::cerr << "No response received, or recvfrom() failed." << std::endl;
}
// 关闭套接字
close(sock);
return 0;
}