客户端无法通过udp连接向服务器发送请求
Client failing to send request to server with udp connection
我正在使用winsock和c++对客户端和服务器进行编程,以返回NTP时间和框时间的偏移量。调试时的问题是客户端无法将请求发送到服务器。失败的特定函数是我的NtpClientThread.cpp
中的sendto
函数这是我的服务器:
#pragma once
#include <iostream>
#include "NtpServer.h"
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <winsock.h>
#include <errno.h>
using std::chrono::system_clock;
namespace ntp
{
struct sockaddr_in server;
struct sockaddr_storage client;
//constructor to create ntp server
NtpServer::NtpServer(u_short portnum, const std::chrono::nanoseconds desiredOffset) : portnum(0), client_length(0), bytes_received(0), current_time(0), desiredOffset(0)
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
throw std::runtime_error("Could not start windows connections.");
}
memset((void *)&server, ' ', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(portnum);
server.sin_addr.s_addr = htonl(INADDR_ANY);
sd = WSASocket(AF_INET, SOCK_DGRAM, 17, NULL, 0, NULL);
if (sd == INVALID_SOCKET)
{
throw std::runtime_error("Could not create socket.");
WSACleanup();
}
if (bind(sd, reinterpret_cast<SOCKADDR *>(&server),
sizeof(server)) == -1)
{
throw std::runtime_error("Could not bind name to socket.");
closesocket(sd);
WSACleanup();
}
}
NtpServer::~NtpServer()
{
closesocket(sd);
WSACleanup();
}
void NtpServer::getResult()
{
ntp_data ntpData = ntp_data();
//set up timeout with blocking
fd_set fds;
int n;
struct timeval tv;
FD_ZERO(&fds);
FD_SET(sd, &fds);
tv.tv_sec = 10; // 10 Secs Timeout
tv.tv_usec = 0;
n = select(sd, &fds, NULL, NULL, &tv);
if (n == 0)
{
exit(0);
}
while (1)
{
//client_length = sizeof(client);
int len = (int)sizeof(struct sockaddr_in);
/* Receive bytes from client */
bytes_received = recvfrom(sd, sendBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
throw std::runtime_error("Could not receive datagram.");
closesocket(sd);
WSACleanup();
}
if (bytes_received < NTP_PACKET_MIN)
{
continue;
}
/* Check for time request */
if (strcmp(readBuffer, "GET TIMErn") == 0)
{
/* Get current time */
system_clock::time_point now = std::chrono::system_clock::now();
auto timepointoffset = (now + desiredOffset).time_since_epoch();
double current_value = std::chrono::duration_cast<std::chrono::duration<double>>(timepointoffset).count();
unpack_ntp(&ntpData, (unsigned char *)readBuffer, bytes_received);
make_packet(&ntpData, NTP_CLIENT, current_value);
pack_ntp((unsigned char *)sendBuffer, NTP_PACKET_MIN, &ntpData);
/* Send data back */
if (sendto(sd, sendBuffer,
(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, client_length) !=
SOCKET_ERROR)
{
throw std::runtime_error("Error sending datagram.");
closesocket(sd);
WSACleanup();
}
}
}
closesocket(sd);
WSACleanup();
}
}
这是我的客户代码:
NTPClientThread::NTPClientThread(Config config) : stopRequested(false), currentOffset((nanoseconds)0), time_point(NULL) {
WORD wVersionRequested;
wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
//INT hp;
try
{
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
throw std::runtime_error("Could not open Windows connection.");
}
/* Open a datagram socket */
sd = WSASocket(AF_INET, SOCK_DGRAM, 17, NULL, 0, NULL);
if (sd == INVALID_SOCKET)
{
WSACleanup();
throw std::runtime_error("Failed to create socket.");
}
/* Clear out server struct */
memset((void *)&server, ' ', sizeof(struct sockaddr_in));
/* Set family and port */
server.sin_family = AF_INET;
inet_pton(AF_INET, config.getValue("NtpHost").c_str(), &(server.sin_addr));
server.sin_port = htons(boost::lexical_cast<u_short>(config.getValue("NtpPort")));
//clear out client struct
memset((void *)&client, ' ', sizeof(struct sockaddr_in));
/* Set family and port */
client.sin_family = AF_INET;
//inet_pton(AF_INET, config.getValue("NtpHost").c_str(), &(client.sin_addr));
client.sin_addr.s_addr = htonl(INADDR_ANY);
client.sin_port = htons(0);
if (bind(sd, reinterpret_cast<SOCKADDR *>(&client)/*result->ai_addr*/,/* result->ai_addrlen*/sizeof(client)) == -1)
{
closesocket(sd);
WSACleanup();
throw std::runtime_error("Failed to bind socket.");
}
ntp_data ntpData = ntp_data();
make_packet(&ntpData, NTP_CLIENT, 0);
pack_ntp((unsigned char *)sendBuffer, NTP_PACKET_MIN, &ntpData);
/* Tranmsit data to get time */
server_length = sizeof(struct sockaddr_in);
if (sendto(sd, (const char *)sendBuffer, sizeof(sendBuffer), 0, (struct sockaddr *)&server/*result->ai_addr*/, server_length/*result->ai_addrlen*/) == -1)
{
throw std::runtime_error("Failed to send request to server.");
}
int bytes_received = recvfrom(sd, (char *)¤t_time, (int)sizeof(current_time), 0, (struct sockaddr *)&server, &server_length);
/* Receive time */
if (bytes_received < 0)
{
throw std::runtime_error("Failed to recieve data from server.");
}
if (bytes_received < NTP_PACKET_MIN)
{
throw std::runtime_error("Received bad responde from server.");
}
unpack_ntp(&ntpData, current_time, server_length);
typedef duration<double, std::ratio<1>>d_seconds;
d_seconds since_epoch_full(ntpData.transmit);
auto since_epoch = duration_cast<system_clock::duration> (since_epoch_full);
system_clock::time_point ntpTime(since_epoch);
system_clock::time_point boxTime = system_clock::now();
currentOffset = ntpTime - boxTime;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
查看inet_pton文档。inet_pton
将表示IP地址的字符串转换为二进制IP地址。它不解析名称,因此无法使用主机名(如localhost
),后者必须进行解析。
您应该使用特定的函数来解析名称,如getaddrinfo
(推荐)或gethostbyname
(已废弃)。
相关文章:
- 每个服务器请求的内存预算
- 从主机向在VirtualBox linux机器上运行的服务器发送http请求
- Capnproto - 在服务器回调中发出客户端请求
- 如果C/C Python3扩展托管HTTP服务器并将Python代码称为请求处理程序,则如何处理并发
- 为什么这C++ASIO,当执行HTTP / SSL请求时,BEAST服务器会进入错误状态
- C++ 对 nodejs 服务器的 POST 请求失败(基于套接字)
- 从远程服务器请求PDB文件
- GPRC服务器在处理的第二请求下崩溃
- 错误请求,您的浏览器发送了此服务器无法理解的请求 - Qt Websocket 服务器
- 如何在服务器端验证用户请求(在我的特定情况下)
- 尝试使用 boost::asio 连接到 SOCKS 5 服务器,但我的连接请求格式不正确
- 如何调用对带有句点的服务器的请求,并在响应无效时再次发送
- 为什么这个简单的服务器在非常低的并发请求上失败
- web服务器如何知道何时完全接收到HTTP请求
- 使用C HTTP请求将文件上传到服务器
- 服务器在 16000 个请求后挂起一段时间
- 使用 select() 的请求/回复服务器。无法写回客户端
- 服务器在请求已经处理请求时收到请求时会崩溃
- C/C SSL请求到CXF服务器
- 服务器在实现 POST 请求时响应字符串不完整