我可以从使用 c++ 和 windows 连接到服务器的套接字获得啥信息?
Posted
技术标签:
【中文标题】我可以从使用 c++ 和 windows 连接到服务器的套接字获得啥信息?【英文标题】:What information can I get from a socket connected to a server using c++ and windows?我可以从使用 c++ 和 windows 连接到服务器的套接字获得什么信息? 【发布时间】:2021-08-15 17:48:44 【问题描述】:我有一个服务器,当客户端连接到服务器时,我想从客户端获取所有信息并用它创建一个结构。 我可以获得什么信息? 我知道我可以从客户端获取 ipv4 和端口,还有什么可以获取的吗?
这是一个简短的方法:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 32406
int main()
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
sockaddr_in hint;
hint.sin_addr.S_un.S_addr = INADDR_ANY;
hint.sin_port = htons(DEFAULT_PORT);
hint.sin_family = AF_INET;
SOCKET listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
bind(listeningSocket, (sockaddr*)&hint, sizeof(sockaddr_in));
listen(listeningSocket, SOMAXCONN);
sockaddr_in socketInfo;
int socketInfoLen = sizeof(socketInfo);
SOCKET clientSocket = accept(listeningSocket, (sockaddr*)&socketInfo, &socketInfoLen);
std::cout << inet_ntoa(socketInfo.sin_addr) << std::endl;
std::cout << socketInfo.sin_port << std::endl;
shutdown(clientSocket, SD_BOTH);
closesocket(clientSocket);
closesocket(listeningSocket);
WSACleanup();
return 0;
【问题讨论】:
套接字和网络不是 C++ (ISO 14882) 的一部分。它们是由其他东西提供的设施,例如 Boost ASIO 或操作系统。您需要参考您在平台上使用的设施的文档。 您使用的是什么 API? 我现在不在家,对不起,我回家后会发布一些代码。 我正在使用 windows sockets api 【参考方案1】:getsockopt
提供了大量信息。它是另一个答案声称的超集,例如
SO_BSP_STATE
返回套接字使用的本地地址、本地端口、远程地址、远程端口、套接字类型和协议。
由于你有一个 TCP 套接字,你会特别感兴趣
IPPROTO_TCP socket options通过WSAIoctl
可以得到不同的信息,例如
其中一些细节将是本地套接字选项(例如阻塞或非阻塞),其他细节将与连接本身有关(例如协商的窗口大小)。一些关于远程客户端的信息会被泄露,尽管不像您使用定制的指纹识别工具那样多。
【讨论】:
你能告诉我如何使用带有 SO_BSP_STATE 标志的 getsockopt 吗?我在互联网上找不到任何有用的东西,或者不知道要寻找什么。谢谢! @ClaudiuHBann:The official documentation 看起来很有用。如果在阅读之后您仍然无法使其工作,那么可能值得提出一个新的专业问题。但是这些特定信息更容易获得viagetsockname()
and getpeername()
as Remy commented already
好像我不知道怎么读 :)) 谢谢【参考方案2】:
客户端没有明确发送的唯一信息是sockaddr_in
结构,即端口和源IP 地址。当然,您只有在客户端启动传输(使用 UDP 发送数据包或使用 TCP 连接)时才会收到此信息。
要获取其他任何内容,客户端需要将其作为常规通信的一部分发送。
【讨论】:
"你得到的唯一信息......是......端口和源 IP 地址" - 这并不完全正确。在 TCP 中,您还可以获取客户端连接的目标 IP 地址和端口。由于服务器绑定到INADDR_ANY
,客户端可以connect()
到任何属于服务器的IP。 accept()
和 getpeername()
会告诉你客户端来自哪里,而getsockname()
会告诉你客户端实际连接到哪里。在 UDP 中,还有WSARecvMsg()
,它可以告诉你一个数据包被发送到哪个 IP 以及实际接收到的网络接口。
如果是 TCP 套接字(这是),也应该有可能(尽管可能很棘手)获取有关 TCP 标头中协商的 TCP 选项的信息,例如窗口大小等。
我认为很明显他想要关于客户端的信息,而不是服务器以上是关于我可以从使用 c++ 和 windows 连接到服务器的套接字获得啥信息?的主要内容,如果未能解决你的问题,请参考以下文章
连接到 IRC 服务器 C++ Windows 10 Visual Studio
我可以从 Java EE webapp 使用 Windows 身份验证连接到 SQL Server 吗?
是否可以从 C# 应用程序连接到 32 位 C++ RPC 服务器应用程序
是否有 C++ CalDav 协议库可以连接到 iCloud//Yahoo [关闭]