我无法使用代码中的IP地址将UDP数据发送到系统。
我们通过构造函数建立连接,然后在下面的代码中发送消息。
这是我的头文件。
class UDPConnect
{
private:
bool connected;
SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
public:
UDPConnect(const int iPort );
UDPConnect(const int iPort , const char* strHostName);
int ReadIncomingPacket(byte *buffer, unsigned int buf_size);
int SendPacket(byte* buffer, unsigned int buf_size , const char*
strHostName);
~UDPConnect();
};
这是函数定义。
UDPConnect::UDPConnect(const int iPORT , const char* strHostName)
{
this->connected = false;
this->s;
WSADATA wsa;
//Initialise winsock
std::cout << ("\nInitialising Winsock...") << std::endl;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
std::cout << ("Failed. Error Code : %d", WSAGetLastError()) <<
std::endl;
exit(EXIT_FAILURE);
}
//Create a socket
if ((this->s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
std::cout << ("Could not create socket : %d", WSAGetLastError());
}
std::cout << ("Socket created.\n");
//Prepare the sockaddr_in structure
this->server.sin_family = AF_INET;
this->server.sin_addr.s_addr = inet_addr( strHostName );
this->server.sin_port = htons(iPORT);
//Bind
//if (::bind(this->s, (struct sockaddr *)&this->server, sizeof(this->server))
== SOCKET_ERROR)
if (::bind(this->s, (struct sockaddr *)&this->server, 0) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
//exit(EXIT_FAILURE);
}
puts("Bind done");
this->connected = true;
}
///////////////////////////////////////////////// /////////////////////////
int UDPConnect::SendPacket(byte *buffer, unsigned int buf_size , const char*
strHostName)
{
this->server.sin_addr.s_addr = inet_addr( strHostName );
if ((this->recv_len = sendto(this->s, (char*)buffer, buf_size + 1, 0,
(struct sockaddr *) &this->si_other, slen)) == SOCKET_ERROR)
{
std::cout << ("No Outgoing packet : %d", WSAGetLastError());
//return -1;
}
return recv_len;
}
答案 0 :(得分:3)
我发现您的代码中有很多错误。
当参数strHostName
实际上不能接受主机名(仅IP地址)时,会引起误解。您应该重命名它们,否则要实现主机名解析。
将printf
样式的说明符与std::cout
混合。
使用无效的bind()
值调用namelen
。第一次您是正确的,但是您将其注释掉了。
递增buf_size
。 UDP对原始字节进行操作,并且原始数据不是以null结尾的,只有C样式的字符串是。如果调用方要发送以null结尾的字符串,则应在传递的buf_size
值中包含null终止符。
使用错误的sendto()
和不确定的sockaddr_in
值调用slen
。另外,不提供任何方法来指定要发送到的目标端口。
尝试更多类似的方法:
class UDPConnect
{
private:
SOCKET s;
public:
UDPConnect(ushort local_port, const char *local_addr = NULL);
~UDPConnect();
int ReadIncomingPacket(byte *buffer, unsigned int buf_size);
int SendPacket(byte* buffer, unsigned int buf_size, const char* remote_addr, ushort remote_port);
};
UDPConnect::UDPConnect(ushort local_port, const char* local_addr)
: s(INVALID_SOCKET)
{
WSADATA wsa;
int err;
//Initialise winsock
std::cout << "\nInitialising Winsock..." << std::endl;
err = WSAStartup(MAKEWORD(2, 2), &wsa);
if (err != 0)
{
std::cout << "Failed. Error Code : " << err << std::endl;
exit(EXIT_FAILURE);
}
//Create a socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
err = WSAGetLastError();
std::cout << "Could not create socket : " << err << std::endl;
exit(EXIT_FAILURE);
}
std::cout << "Socket created." << std::endl;
//Prepare the sockaddr_in structure
struct sockaddr_in server = {};
server.sin_family = AF_INET;
server.sin_port = htons(local_port);
if (local_addr)
{
server.sin_addr.s_addr = inet_addr(local_addr);
if (server.sin_addr.s_addr == INADDR_NONE)
{
std::cout << "Invalid local address specified" << std::endl;
closesocket(s);
exit(EXIT_FAILURE);
}
}
else
server.sin_addr.s_addr = INADDR_ANY;
//Bind
if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
err = WSAGetLastError();
std::cout << "Bind failed with error code : " << err << std::endl;
closesocket(s);
exit(EXIT_FAILURE);
}
std::cout << "Bind done";
}
UDPConnect::~UDPConnect()
{
closesocket(s);
}
int UDPConnect::ReadIncomingPacket(byte *buffer, unsigned int buf_size)
{
int recv_len;
if ((recv_len = recvfrom(s, (char*)buffer, buf_size, 0, NULL, NULL)) == SOCKET_ERROR)
{
int err = WSAGetLastError();
std::cout << "No Incoming packet : " << err;
//return -1;
}
return recv_len;
}
int UDPConnect::SendPacket(byte *buffer, unsigned int buf_size, const char* remote_addr, ushort remote_port)
{
struct sockaddr_in si_other = {};
int send_len;
//Prepare the sockaddr_in structure
si_other.sin_family = AF_INET;
si_other.sin_addr.s_addr = inet_addr(remote_addr);
si_other.sin_port = htons(remote_port);
if ((send_len = sendto(s, (char*)buffer, buf_size, 0, (struct sockaddr *) &si_other, sizeof(si_other))) == SOCKET_ERROR)
{
int err = WSAGetLastError();
std::cout << "No Outgoing packet : " << err;
//return -1;
}
return send_len;
}