为什么包含 "boost/multiprecision/cpp_int.hpp" 会破坏套接字?
Why does including "boost/multiprecision/cpp_int.hpp" ruins socket?
我有服务器应用程序的工作代码。
现在我需要在我的项目中使用 cpp_int。
但是,当我只是尝试包含 boost/multiprecision/cpp_int.hpp
accept(listeningSocket, (sockaddr*)&client, &sizeofclient);
returns 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;
}
有什么想法吗?
问题是您使用 using namespace std;
的副作用。
当您包含 <boost/multiprecision/cpp_int.hpp>
时,它会从 C++ 的 <functional>
header 中引入 std::bind()
,这就是您的代码最终调用的函数,而不是 Winsock 的 bind()
函数。因此,listen()
和 accept()
失败是因为服务器套接字未绑定到网络接口(并且您的代码未检查 bind()
和 listen()
上的错误)。如果您检查了 listen()
和 accept()
的错误代码,您会发现它们都报告了 WSAEINVAL
(分别表示 "The socket has not been bound with bind" 和 "The listen function was not invoked prior to accept")。
您需要
Get rid of using namespace std;
,然后在需要的地方明确使用std::
前缀(这是首选方案!)
在调用bind()
时,可以在前面加上::
,告诉编译器你要从全局命名空间调用bind()
函数(Win32 API,如 Winsock,不使用 C++ 中的名称空间),而是使用 std
名称空间中的名称空间。
我有服务器应用程序的工作代码。 现在我需要在我的项目中使用 cpp_int。 但是,当我只是尝试包含 boost/multiprecision/cpp_int.hpp
accept(listeningSocket, (sockaddr*)&client, &sizeofclient);
returns 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;
}
有什么想法吗?
问题是您使用 using namespace std;
的副作用。
当您包含 <boost/multiprecision/cpp_int.hpp>
时,它会从 C++ 的 <functional>
header 中引入 std::bind()
,这就是您的代码最终调用的函数,而不是 Winsock 的 bind()
函数。因此,listen()
和 accept()
失败是因为服务器套接字未绑定到网络接口(并且您的代码未检查 bind()
和 listen()
上的错误)。如果您检查了 listen()
和 accept()
的错误代码,您会发现它们都报告了 WSAEINVAL
(分别表示 "The socket has not been bound with bind" 和 "The listen function was not invoked prior to accept")。
您需要
Get rid of
using namespace std;
,然后在需要的地方明确使用std::
前缀(这是首选方案!)在调用
bind()
时,可以在前面加上::
,告诉编译器你要从全局命名空间调用bind()
函数(Win32 API,如 Winsock,不使用 C++ 中的名称空间),而是使用std
名称空间中的名称空间。