gpt4 book ai didi

c++ - 通过 Winsock 发送键盘缓冲区

转载 作者:行者123 更新时间:2023-11-30 03:07:55 25 4
gpt4 key购买 nike

现在我是 WINSOCK 的新手,对 C++ 不是很流利,所以请多多包涵。我编写了一个 NetworkServer 和 NetworkClient 类,主要基于 MSDN 教程。客户端将向服务器发送一个大小为 256 的字符数组,其中包含每个标准键盘按钮的状态(0 表示该键未被按下,1 表示它被按下)。

运行代码时,我首先启动服务器,然后是客户端。他们相互连接良好。然后调用客户端发送键盘缓冲区。发送缓冲区,但服务器挂起:

receiveResult = recv(theClient, buffer, sizeof(buffer), 0);

每个类中的“keys”变量是一个字符键[256],用于保存每个键状态。

下面是网络服务器启动后发生的循环:

char buffer[256];
int receiveResult, sendResult;

// Receive from the client
do
{
receiveResult = recv(theClient, buffer, sizeof(buffer), 0);
if (receiveResult > 0 )
{
sendResult = send(theClient, buffer, receiveResult, 0);
if (sendResult == SOCKET_ERROR)
{
sendResult = WSAGetLastError();
JBS::reportSocketError(nret, "server send()");
closesocket(theClient);
WSACleanup();
return;
}
else
{
memcpy(keys, buffer, sizeof(keys));
}
}

else if (receiveResult == 0)
cout << "Server closing." << endl;
else
{
receiveResult = WSAGetLastError();
JBS::reportSocketError(nret, "server receive()");
closesocket(theClient);
WSACleanup();
return;
}
} while (receiveResult > 0);

这里是 NetworkClient 发送方法:

char buffer[256];
memcpy(buffer, keys, sizeof(buffer));

nret = send(theSocket, buffer, sizeof(buffer),0);
if (nret == SOCKET_ERROR)
{
nret = WSAGetLastError();
JBS::reportSocketError(nret, "client send()");
closesocket(theSocket);
WSACleanup();
}
do
{
char buff[256];
nret = recv(theSocket, buff, sizeof(buff), 0);
if (nret > 0)
{
memcpy(keys, buff, sizeof(keys));
}
else if (nret == 0)
cout << "Server connection closed" << endl;
else
{
nret = WSAGetLastError();
JBS::reportSocketError(nret, "client receive()");
closesocket(theSocket);
WSACleanup();
}

} while (nret > 0);

正如我所说,正在客户端和服务器之间建立连接,但进程的接收部分似乎无法正常工作。任何帮助将不胜感激。

NetworkClient的启动方法:

sockVersion = MAKEWORD(1, 1);

// Initialize Winsock as before
WSAStartup(sockVersion, &wsaData);

// Store information about the server
LPHOSTENT hostEntry;

hostEntry = gethostbyname(serverAddress); // Specifying the server by its name;

if (!hostEntry) {
nret = WSAGetLastError();
JBS::reportSocketError(nret, "client gethostbyname()"); // Report the error as before
closesocket(theSocket);
WSACleanup();
}

// Create the socket
theSocket = socket(AF_INET, // Go over TCP/IP
SOCK_STREAM, // This is a stream-oriented socket
IPPROTO_TCP); // Use TCP rather than UDP

if (theSocket == INVALID_SOCKET) {
nret = WSAGetLastError();
JBS::reportSocketError(nret, "client socket()");
closesocket(theSocket);
WSACleanup();
}

// Fill a SOCKADDR_IN struct with address information
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
serverInfo.sin_port = htons(PORT); // Change to network-byte order and
// insert into port field

// Connect to the server
nret = connect(theSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));

if (nret == SOCKET_ERROR)
{
nret = WSAGetLastError();
JBS::reportSocketError(nret, "client connect()");
closesocket(theSocket);
WSACleanup();
}
// Successfully connected!
started = true;

最佳答案

在客户端代码中,您写道:

char buff[256];
nret = recv(theSocket, buff, (int)strlen(buff), 0);

这意味着您要将数据接收到长度为strlen(buff) 的缓冲区中。不幸的是,strlen() 返回缓冲区内 string 的长度,即缓冲区内任何 NUL 字符之前的数据长度。你的编译器足够聪明,用 NUL 字符初始化 buff,因此 strlen(buf) 返回 0,这意味着你想接收 0 字节的数据。因此,recv() 没有收到任何东西。

你的意思是:

nret = recv(theSocket, buff, sizeof(buff), 0);

(如果您尝试使用 Release 版本编译您的程序,它会很高兴地崩溃,因为 buff 将不会被初始化,并且 strlen()会返回一个相当随机的结果,这会导致程序访问无效的内存地址...)

我应该补充一点,你声明你的缓冲区的方式是不幸的:你有一个 bool 数组(值 1 或 0 取决于键的状态)。 bool 值不是字符。严格的声明应该是 bool buff[256]...

关于c++ - 通过 Winsock 发送键盘缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5521838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com