C++ TCP 服务器 (Winsock) 连接 (无效客户端) 然后立即关闭
C++ TCP Server (Winsock) Connecting (invalid client) Instantly Then Closes
编辑:正在研究解决方案 - 事实证明,谷歌搜索 204.204.204.204 让我比更多的描述性请求更进一步。
真诚地。智慧结束。我不知道我怎么能花一整天的时间做一些在Flask(服务器)和Javascript(客户端)中花了10分钟的事情。我需要它以C++运行,并允许客户端通过同一台机器上的BlueStacks端口进行连接。客户并不重要,因为我甚至无法走那么远。
我尝试过WinSocks,我尝试过WxWidget的网络实现,我什至尝试过一些随机C++包装器的东西。所有这些都失败了(通常在示例中!例如,到处复制粘贴和错误)。所以我最终回到了WinSockets,并在YouTube上学习了一个教程。
int ServerStuff() {
WSADATA WsData;
WORD ver = MAKEWORD(2, 2);
int wsOK = WSAStartup(ver, &WsData);
if (wsOK != 0) {
wxLogMessage("Can't initialize Winsock! Quitting");
return false;
}
//Create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET) {
wxLogMessage("Can't create a socket! Quitting");
return false;
}
//Bind the ip and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; //Could also use inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
//Tell winsock the socket is for listening
listen(listening, SOMAXCONN);
//Wait for a connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
//if (clientSocket == INVALID_SOCKET) {
// wxLogMessage("Client Invalid Socket");
// return false;
//}
char host[NI_MAXHOST]; //Client's remote name
char service[NI_MAXHOST]; //Service (port) the client is connected on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) {
wxLogMessage("Can't initialize Winsock! Quitting");
}
else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
wxLogMessage(host);
int wut = client.sin_port;
wxString mystring = wxString::Format(wxT("%i"), wut);
wxLogMessage("Connected on port");
wxLogMessage(mystring);
//wxLogMessage(to_string(ntohs(client.sin_port)));
}
wxLogMessage("Got this far somehow");
//Close listening socket - we don't need it anymore - later on we'll learn how to accept multiple client
closesocket(listening);
//while loop: accept and echo message back to client
char buf[4096];
while (true)
{
ZeroMemory(buf, 4096);
//Wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR) {
//wxLogMessage("ERROR in recv");
break;
}
if (bytesReceived == 0) {
wxLogMessage("Client Disconnected");
break;
}
//Echo back to client
send(clientSocket, buf, bytesReceived + 1, 0);
//Close the socket
closesocket(clientSocket);
//Cleanup winsock
WSACleanup();
wxLogMessage("Welp");
}
}
// event handlers
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// true is to force the frame to close
ServerStuff();
//Close(true);
}
在YouTube视频("在C++中创建TCP服务器" - 不允许发布链接)这是有效的!命令窗口打开,无限空白,直到他连接客户端,然后客户端发送消息,服务器回复相同的确切消息作为回报。
不是我的。我的只是匆匆忙忙地完成所有事情,然后关闭。我的日志曾经立即退出注释的代码,其中指出客户端套接字无效,所以我将其注释掉。现在我的输出是: 204.204.204.204 在端口上连接 52428 不知何故走到了这一步
我不知道该怎么办。我只是尝试通过同一台机器的TCP连接发送数据。我很困惑这怎么这么难。似乎某个随机进程立即尝试作为客户端连接到我的服务器?但是,当我在 54000 上显式托管时,为什么允许它在端口 52428 上进行连接?
我的目标: 启动服务器 使用 BlueStacks 中的 Java 应用程序连接到服务器 将数据从服务器发送到客户端
将计算机作为服务器更有意义,因为将有多个BlueStacks实例,我宁愿不必为我正在做的事情"生成"多个程序/服务器。
我在您的套接字代码中看到一些错误。
-
如果成功,则不调用
然后出现问题。WSACleanup()
WSAStartup()
-
如果
socket()
成功,然后出现问题,则不打电话closesocket()
。 -
不将您传递给
bind()
sockaddr_in
归零。 结构中的随机字节可能会导致bind()
失败。 -
忽略
bind()
、listen()
、accept()
和send()
的返回值。 -
未正确处理
getnameinfo()
的返回值。 它在成功时返回 0,而不是失败。 -
向客户端发送比从客户端收到的字节多 +1 个字节。 如果客户端发送的字节数少于缓冲区可以容纳的字节数,则由于调用
ZeroMemory()
,该额外字节将被0x00。 但是,如果客户端实际上发送了足够的字节来完全填满缓冲区,那么您将从不属于您的内存中发送一个额外的字节。 如果您确实想在回显所有内容之后发送空终止符,请显式执行此操作。 否则,真正的回显服务器应该只发回它收到的确切内容,不多也不少。
尝试更多类似的东西:
void ServerStuff() {
WSADATA WsData;
int ret = WSAStartup(MAKEWORD(2, 2), &WsData);
if (ret != 0) {
wxLogMessage("Can't initialize Winsock! Error: %d", ret);
return;
}
//Create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listening == INVALID_SOCKET) {
wxLogMessage("Can't create a socket! Error: %d", WSAGetLastError());
WSACleanup();
return;
}
//Bind the ip and port to a socket
sockaddr_in hint = {};
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.s_addr = INADDR_ANY; //Could also use inet_pton
ret = bind(listening, (sockaddr*)&hint, sizeof(hint));
if (ret == SOCKET_ERROR) {
wxLogMessage("Can't bind socket! Error: %d", WSAGetLastError());
closesocket(listening);
WSACleanup();
return;
}
//Tell winsock the socket is for listening
ret = listen(listening, SOMAXCONN);
if (ret == SOCKET_ERROR) {
wxLogMessage("Can't listen on socket! Error: %d", WSAGetLastError());
closesocket(listening);
WSACleanup();
return;
}
//Wait for a connection
sockaddr_in client = {};
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET) {
wxLogMessage("Can't accept a client! Error: %d", WSAGetLastError());
closesocket(listening);
WSACleanup();
return;
}
char host[NI_MAXHOST] = {}; //Client's remote name
ret = getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, NULL, 0, 0);
if (ret != 0) {
wxLogMessage("Can't get client name info! Error: %d", ret);
inet_ntop(AF_INET, &(client.sin_addr), host, NI_MAXHOST);
}
wxLogMessage("Client: %s, Connected on port: %hu", host, ntohs(client.sin_port));
//Close listening socket - we don't need it anymore - later on we'll learn how to accept multiple client
closesocket(listening);
//while loop: accept and echo message back to client
char buf[4096];
int bytesReceived;
while (true)
{
//Wait for client to send data
bytesReceived = recv(clientSocket, buf, sizeof(buf), 0);
if (bytesReceived == SOCKET_ERROR) {
wxLogMessage("Can't read from client! Error: ", WSAGetLastError());
break;
}
if (bytesReceived == 0) {
wxLogMessage("Client Disconnected");
break;
}
//Echo back to client
ret = send(clientSocket, buf, bytesReceived, 0);
if (ret == SOCKET_ERROR) {
wxLogMessage("Can't send to client! Error: ", WSAGetLastError());
break;
}
}
//Close the socket
closesocket(clientSocket);
//Cleanup winsock
WSACleanup();
wxLogMessage("Welp");
}
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 使用调试/崩溃报告将应用程序部署到客户端
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 从服务器传输到客户端的消息不会出现
- OpenSSL TLS服务器-使用客户端证书白名单
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何绑定 C++ gRPC 客户端的网络接口
- C++套接字客户端到 Python 服务器未创建连接
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 将相机数据从服务器实时流式传输到客户端
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- GRPC C++ TLS 客户端 grpc::SslCredentials() 方法不返回
- boost::asio::ip::tcp::iostream,先启动客户端,然后等待服务器
- C++ TCP 服务器 (Winsock) 连接 (无效客户端) 然后立即关闭
- 在服务器上执行命令,然后将结果发送到Windows中的客户端