Почему включается сокет руин «boost / multiprecision / cpp_int.hpp»? - PullRequest
1 голос
/ 29 апреля 2019

У меня есть рабочий код серверного приложения.Теперь мне нужно использовать cpp_int в моем проекте.Однако, когда я просто пытаюсь включить boost / multiprecision / cpp_int.hpp

accept (listenSocket, (sockaddr *) & client, & sizeofclient);

возвращает INVALID_SOCKET , и программа завершается с кодом 3.

Это код server.cpp

#include <iostream>
#include <Ws2tcpip.h>
//#include <boost/multiprecision/cpp_int.hpp> // reason of the probmlem
#pragma comment(lib, "ws2_32.lib")
constexpr auto MSIZE = 4096;
using namespace std;

int main()
{
    WSADATA wsData;
    WORD ver = MAKEWORD(2, 2);
    if (WSAStartup(ver, &wsData) != 0)
    {
        cerr << "Can't initialise winsock\nQuiting...\n";
        return 1;
    }   
    SOCKET listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (listeningSocket == INVALID_SOCKET)
    {
        cerr << "Can't create a socket!\nQuiting...\n";
        return 2;
    }
    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(54000);
    hint.sin_addr.S_un.S_addr = INADDR_ANY;
    bind(listeningSocket, (sockaddr*)&hint, sizeof(hint));
    listen(listeningSocket, SOMAXCONN);
    cout << "Listenning\n";
    sockaddr_in client;
    int sizeofclient = sizeof(client);
    SOCKET clientSocket = accept(listeningSocket, (sockaddr*)&client, &sizeofclient);
    if (clientSocket == INVALID_SOCKET)
    {
        cerr << "Invalid socket.\nQuiting...\n";
        return 3;
    }

    char host[NI_MAXHOST];
    char service[NI_MAXHOST];
    ZeroMemory(host, NI_MAXHOST);
    ZeroMemory(service, NI_MAXHOST);
    char buf[MSIZE];
    while (1)
    {
        ZeroMemory(buf, MSIZE);
        int bytesReceived = recv(clientSocket, buf, MSIZE, 0);
        if (bytesReceived == SOCKET_ERROR)
        {
            cerr << "Error in recv()\n";
            break;
        }
        if (bytesReceived == 0)
        {
            cout << "Client disconnected" << endl;
            break;
        }
        if (strcmp("\r\n", buf) != 0)
        {
            cout << "(Request from " << host << ") >>  " << buf << endl;
            if (strcmp(buf, "hello") == 0)
            {
                char response[100] = "Greetings!\n\r";
                send(clientSocket, response, sizeof(response) + 1, 0);
            }
            else 
            {
                char response[100] = "Invalid command!\n\r";
                send(clientSocket, response, sizeof(response) + 1, 0);
            }
        }
    }
    cout << "Quiting program\n";
    return 0;
}

Есть идеи?

1 Ответ

4 голосов
/ 29 апреля 2019

Проблема заключается в побочном эффекте использования using namespace std;.

Когда вы включаете <boost/multiprecision/cpp_int.hpp>, он извлекает std::bind() из заголовка <functional> в C ++, и это функция, которую ваш код в конечном итоге вызывает вместо функции bind() Winsock. Таким образом, listen() и accept() завершаются ошибкой, поскольку сокет сервера не связан с сетевым интерфейсом (и ваш код не проверяет ошибки на bind() и listen()). Если бы вы проверили коды ошибок для listen() и accept(), вы бы увидели, что они оба сообщают WSAEINVAL (что означает «Сокет не был связан с привязкой» и «Функция прослушивания не была вызвана до принятия»). соответственно.

Вам нужно либо

  • Избавьтесь от using namespace std;, а затем явно используйте префикс std::, где это необходимо (это предпочтительное решение!)

  • при вызове bind() вы можете использовать префикс ::, чтобы сообщить компилятору о том, что вы хотите вызвать функцию bind() из глобального пространства имен (Win32 API, такие как Winsock, не используют пространства имен в C ++), а не из пространства имен std.

...