UDP-сервер перезагружается каждые 5 секунд - PullRequest
0 голосов
/ 20 сентября 2019

Я пишу впервые на этом языке и могу написать только этот 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();

        }
    }

Ответы [ 2 ]

0 голосов
/ 21 сентября 2019
#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();

        }

    }
}
0 голосов
/ 20 сентября 2019

Перевод задачи с помощью google translate:

  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 / WSACleanup и socket / closesocket для управления полученными ресурсами.

...