我的 STUN 绑定请求哪里出了问题
Where is wrong with my STUN Binding request
我向 stun.l.google.com:19305
发送了 udp 请求,但我没有从 google 眩晕服务器收到任何响应。我省略了这段代码中的所有错误检查。我的程序挂在 recvfrom
.
int stun_socket = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in stun_client;
memset(&stun_client, 0, sizeof(stun_client));
stun_client.sin_family = AF_INET;
stun_client.sin_port = htons(local_port);
int rc = bind(stun_socket, (struct sockaddr *)&stun_client, sizeof(stun_client));
struct sockaddr_in stun_server;
memset(&stun_server, 0, sizeof(stun_server));
stun_server.sin_family = AF_INET;
stun_server.sin_port = htons(remote_port);
inet_pton(AF_INET, server, &stun_server.sin_addr);
typedef struct stun_header_tag {
uint16_t message_type;
uint16_t message_length;
unsigned char transaction_id[16];
} stun_header_t;
stun_header_t header;
header.message_type = htons(0x0001); /* Binding Request */
header.message_length = htons(0);
*(int *)(&header.transaction_id[8]) = 0xFFEEFFEE; /* transaction id in the response should keep consistent with this one */
rc = sendto(stun_socket, (void *)&header, sizeof(header), 0, (struct sockaddr *)&stun_server, sizeof(stun_server));
char response[64];
rc = recvfrom(stun_socket, response, 64, 0, NULL, 0);
我猜你正在做类似或等效的事情来发送数据:
sendto(sock, &header, sizeof(header), (sockaddr*)&addr, addrlen);
如果是这种情况,您可能忘记将 message_type 值转换为网络字节顺序(大端)。
试试这个:
header.message_type = htons(0x0001);
但如果您想要更好的解决方案,并且可以使用 C++,请使用 Stuntman. You can generate a binding request as follows with the C++ class, CStunMessageBuilder, declared in the stuncore/stunbuilder.h 文件中内置的客户端库。
CStunMessageBuilder builder;
StunTransactionId transId;
builder.AddBindingRequestHeader();
builder.AddRandomTransactionId(&transID);
unsigned char* msg = builder.GetStream().GetDataPointerUnsafe();
size_t len = builder.GetStream().GetSize();
sendto(sock, msg, len, (sockaddr*)&addr, addrlen);
我向 stun.l.google.com:19305
发送了 udp 请求,但我没有从 google 眩晕服务器收到任何响应。我省略了这段代码中的所有错误检查。我的程序挂在 recvfrom
.
int stun_socket = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in stun_client;
memset(&stun_client, 0, sizeof(stun_client));
stun_client.sin_family = AF_INET;
stun_client.sin_port = htons(local_port);
int rc = bind(stun_socket, (struct sockaddr *)&stun_client, sizeof(stun_client));
struct sockaddr_in stun_server;
memset(&stun_server, 0, sizeof(stun_server));
stun_server.sin_family = AF_INET;
stun_server.sin_port = htons(remote_port);
inet_pton(AF_INET, server, &stun_server.sin_addr);
typedef struct stun_header_tag {
uint16_t message_type;
uint16_t message_length;
unsigned char transaction_id[16];
} stun_header_t;
stun_header_t header;
header.message_type = htons(0x0001); /* Binding Request */
header.message_length = htons(0);
*(int *)(&header.transaction_id[8]) = 0xFFEEFFEE; /* transaction id in the response should keep consistent with this one */
rc = sendto(stun_socket, (void *)&header, sizeof(header), 0, (struct sockaddr *)&stun_server, sizeof(stun_server));
char response[64];
rc = recvfrom(stun_socket, response, 64, 0, NULL, 0);
我猜你正在做类似或等效的事情来发送数据:
sendto(sock, &header, sizeof(header), (sockaddr*)&addr, addrlen);
如果是这种情况,您可能忘记将 message_type 值转换为网络字节顺序(大端)。
试试这个:
header.message_type = htons(0x0001);
但如果您想要更好的解决方案,并且可以使用 C++,请使用 Stuntman. You can generate a binding request as follows with the C++ class, CStunMessageBuilder, declared in the stuncore/stunbuilder.h 文件中内置的客户端库。
CStunMessageBuilder builder;
StunTransactionId transId;
builder.AddBindingRequestHeader();
builder.AddRandomTransactionId(&transID);
unsigned char* msg = builder.GetStream().GetDataPointerUnsafe();
size_t len = builder.GetStream().GetSize();
sendto(sock, msg, len, (sockaddr*)&addr, addrlen);