UDP 服务器每 5 秒重新启动一次

UDP Server Restart every 5 seconds

本文关键字:一次 重新启动 服务器 UDP      更新时间:2023-10-16

我是第一次用这种语言写作,只能写这个 UDP 服务器和客户端。我需要帮助;我想服务器等待响应并显示它。如果在 5 秒内未收到答案,程序将再次开始执行。如果你不明白任务,你可以翻译任务(第五个(:https://www.opennet.ru/docs/RUS/socket/node15.html

#include <iostream>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void main()
{
struct timeval tv;
fd_set fd;
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
cout << "Server opened" << endl;
if (wsOk != 0)
{
cout << "Can't start Winsock! " << wsOk;
return;
}
SOCKET in = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in serverHint;
serverHint.sin_addr.S_un.S_addr = ADDR_ANY; 
serverHint.sin_family = AF_INET; 
serverHint.sin_port = htons(54000); 
if (bind(in, (sockaddr*)& serverHint, sizeof(serverHint)) == SOCKET_ERROR)
{
cout << "Can't bind socket! " << WSAGetLastError() << endl;
return;
}
sockaddr_in client; 
int clientLength = sizeof(client); 
char buf[1024];
while (true)
{
FD_ZERO(&fd);
FD_SET(in, &fd);
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(0, &fd, NULL, NULL, &tv) > 0)
{
ZeroMemory(&client, clientLength);
ZeroMemory(buf, 1024);
int bytesIn = recvfrom(in, buf, 1024, 0, (sockaddr*)& client, &clientLength);
if (bytesIn == SOCKET_ERROR)
{
cout << "Error receiving from client " << WSAGetLastError() << endl;
continue;
}
char clientIp[256];
ZeroMemory(clientIp, 256);
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);
cout << "Message recv from " << clientIp << " : " << buf << endl;
}
else  {
cout << "Timeout" << endl;
closesocket(in);
break;
}
closesocket(in);
WSACleanup();
}
}

谷歌翻译的任务翻译:

  1. 编写一个程序,要求用户提供 IP 地址、端口号和文本字符串,
  2. 使用 UDP 协议将字符串发送到指定地址,
  3. 等待响应,并将其显示在屏幕上。
    • 如果在 5 秒内未收到答案,程序将再次开始执行。

您的程序完全缺少第 1 部分和第 2 部分,因此您必须添加它们。

对于第 3 部分,移动当前的while循环,使其涵盖main中的所有内容:

int main() // note: main must be declared to return 'int'
{
while(true) { // new start of the while loop, first in main
// ... your current code until the below line ...
cout << "Message recv from " << clientIp << " : " << buf << endl;
// exit program if you've received a response
closesocket(in);
break; // break out of while loop
}
else {
cout << "Timeout" << endl;
}
closesocket(in);
WSACleanup();
} // end of while loop
WSACleanup();
} // end of main

这个重新初始化器 Winsock2 用于每次不必要的尝试,它也在多个地方closesocket。我会为WSAStartup/WSACleanupsocket/closesocket添加类来管理他们获得的资源。

#include <iostream>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void main()
{
struct timeval tv;
fd_set fd;
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
cout << "5" << endl;
if (wsOk != 0)
{
cout << "Winsock" << wsOk;
return;
}
SOCKET in = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in serverHint;
serverHint.sin_addr.S_un.S_addr = ADDR_ANY; 
serverHint.sin_family = AF_INET; 
serverHint.sin_port = htons(54000); 
if (bind(in, (sockaddr*)& serverHint, sizeof(serverHint)) == SOCKET_ERROR)
{
cout << "hhhh" << WSAGetLastError() << endl;
return;
}
sockaddr_in client; 
int clientLength = sizeof(client); 
char buf[1024];
while (true)
{
FD_ZERO(&fd);
FD_SET(in, &fd);
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(0, &fd, NULL, NULL, &tv) > 0)
{
ZeroMemory(&client, clientLength);
ZeroMemory(buf, 1024);
int bytesIn = recvfrom(in, buf, 1024, 0, (sockaddr*)& client, &clientLength);
if (bytesIn == SOCKET_ERROR)
{
cout << "EEEROOR" << WSAGetLastError() << endl;
continue;
}
char clientIp[256];
ZeroMemory(clientIp, 256);
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);
cout << "С " << clientIp << " : " << buf << endl;
closesocket(in);
WSACleanup();
exit(0);
}
else  {
cout << "jhkjhkjhjn" << endl;
closesocket(in);
main();
}
}
}