Я написал две простые программы, обе с использованием UDP. Один из них отправляет пакеты данных, а другой получает их.
Я запустил обе эти программы в следующих случаях:
- Брандмауэр был отключен.
- Я переадресовал соответствующий порт, хотя я проверял его в локальной сети.
Я тестировал его при использовании localhost, запустил обе программы на одном компьютере. Но это не работает.
Программа отправителя:
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define PORT 1243
#define PORTSTR "1243"
#define IPSTR "127.0.0.1"
#define CYCLECOUNT 100
#define MESS "Hello world!"
int main()
{
/// True if the socket is initialized.
bool bSockInit = false;
/// Initialization.
WSADATA wsaData;
if (int err; (err = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{
std::cout << "Failed the startup with error: " << err << '\n';
goto END;
}
/// Creating the socket.
SOCKET sock;
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
std::cout << "Failed the socket with error: " << WSAGetLastError() << '\n';
goto END;
}
bSockInit = true;
/// Creating the address, to which data is sent.
sockaddr_in remoteAddr;
ZeroMemory((PVOID) &remoteAddr, sizeof(remoteAddr));
// Setting the address familiy to ipv4.
remoteAddr.sin_family = AF_INET;
// Setting the port in network byte order.
remoteAddr.sin_port = htons(PORT);
// Setting the address from a c-style string.
InetPton(AF_INET, TEXT(IPSTR), (PVOID) &remoteAddr.sin_addr);
/// Sending the messages.
while (std::cin.get() == '\n')
{
int byteCount = 0;
for (int i = 0; i < CYCLECOUNT; ++i)
{
byteCount += sendto(sock, MESS, sizeof(MESS), 0, (sockaddr*) &remoteAddr, sizeof(remoteAddr));
}
/// Print the number of bytes sent.
std::cout << "Sent " << byteCount << " bytes times to " IPSTR ":" PORTSTR << ".";
}
END:
// If the socket was initialized successfully then dispose of it.
if (bSockInit)
{
std::cout << "closesocket finished with code: " << closesocket(sock) << '\n';
}
std::cout << "WSACleanup finished with code: " << WSACleanup() << '\n';
std::cin.get();
return 0;
}
Программа получателя:
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib, "Ws2_32.lib")
// The port where data is to be received.
#define PORT 1243
int main(int argc, char** argv)
{
/// True if the socket is initialized.
bool bSockInit = false;
/// Initialization.
WSADATA wsaData;
if (int err; (err = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{
std::cout << "Failed the startup with error: " << err << '\n';
goto END;
}
/// Creating the socket.
SOCKET sock;
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
std::cout << "Failed the socket with error: " << WSAGetLastError() << '\n';
goto END;
}
bSockInit = true;
/// Creating the address.
sockaddr_in thisAddr;
ZeroMemory((PVOID) &thisAddr, sizeof(thisAddr));
// Setting the address familiy to ipv4.
thisAddr.sin_family = AF_INET;
// Setting the port in network byte order.
thisAddr.sin_port = htons(PORT);
// Setting the address to any, so that incoming data, whichever the ipv4-address is, is accepted.
thisAddr.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
if (bind(sock, (sockaddr*)&thisAddr, sizeof(thisAddr)) == SOCKET_ERROR)
{
std::cout << "Failed the bind with error: " << WSAGetLastError() << '\n';
goto END;
}
// Buffer to store incoming bytes.
char buf[1024];
// The number of bytes that were received.
int len;
// Data about the sender.
sockaddr from;
int fromlen;
fromlen = 0;
// ~Data about the sender.
// Waiting for a message, containing at least one byte to arrive.
while ((len = recvfrom(sock, buf, sizeof(buf), NULL, &from, &fromlen)) <= 0);
// Printing the message that was just received and placed into the buffer.
for (int i = 0; i < len; ++i)
{
std::cout << buf[i];
}
END:
// If the socket was initialized successfully then dispose of it.
if (bSockInit)
{
std::cout << "closesocket finished with code: " << closesocket(sock) << '\n';
}
std::cout << "WSACleanup finished with code: " << WSACleanup() << '\n';
std::cin.get();
return 0;
}
Если у вас есть свободное время, запустите обе программы и посмотрите, что произойдет.
Для отправки данных с помощью программы отправителя вам необходимо нажать клавишу ENTER / RETURN.
Буду также признателен за примеры таких программ, которые работают.