Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 记录WSASend缓冲区并发送它们_C++_Winsock2 - Fatal编程技术网

C++ 记录WSASend缓冲区并发送它们

C++ 记录WSASend缓冲区并发送它们,c++,winsock2,C++,Winsock2,我想让作弊成为一种不受欢迎的游戏。每次游戏调用WSASend函数时,lpBuffers变量中都有一个一定长度的缓冲区。我需要这样做,当按下我的侧边鼠标按钮时,缓冲区被写入某种数组。然后,当释放按钮时,检查数组中是否有内容,如果有,则逐个发送每个缓冲区。欺骗的本质是,当快速发送记录的数据时,我的角色会突然从一个点移动到另一个点,或者非常快地执行其他一些操作。我编写了以下代码,但它不能正常工作 std::vector<std::string> records; WSABUF buffer

我想让作弊成为一种不受欢迎的游戏。每次游戏调用WSASend函数时,lpBuffers变量中都有一个一定长度的缓冲区。我需要这样做,当按下我的侧边鼠标按钮时,缓冲区被写入某种数组。然后,当释放按钮时,检查数组中是否有内容,如果有,则逐个发送每个缓冲区。欺骗的本质是,当快速发送记录的数据时,我的角色会突然从一个点移动到另一个点,或者非常快地执行其他一些操作。我编写了以下代码,但它不能正常工作

std::vector<std::string> records;
WSABUF buffer;

/*
    The WSASend function leads to __WSASend. The original WSASend function is in _WSASend.
*/

int WSAAPI __WSASend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
    if (GetAsyncKeyState(VK_XBUTTON1) < 0) // If the side mouse button is pressed when calling WSASend, write the buffer data to my array of strings
    {
        records.emplace_back(lpBuffers->buf);

/*
While the mouse button is held down, the game will think that the data was sent because * lpNumberOfBytesSent = lpBuffers-> len; This is necessary in order for the game to send new data.
*/

        *lpNumberOfBytesSent = lpBuffers->len; 
        return 0;
    }


/* I need to send data with a delay, but I cannot use the Sleep () function since WSASend and WSARecv are on the same thread. Since the game tries to send the same data if it just returns 0 (without setting * lpNumberOfBytesSent = lpBuffers-> len) I decided to take advantage of this. */
    if (records.size() > 0)
    {
        buffer.buf = &records[0][0];
        buffer.len = records[0].length();
        _WSASend(s, &buffer, 1, 0, 0, 0, 0);
        records.erase(records.begin());

/* No delay because I decided to check if it works at all. And as it turned out, it works, but very rarely. When the saved data was small - 50 to 50 that will go and everything will be ok, but when there is a lot, it always kicks from the server with a data read error. */

        return 0; // I am returning 0 without setting * lpNumberOfBytesSent = lpBuffers-> len; so that the game calls the same function again with the same data to send next recorded buffer data
    }

    return _WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); // When there is no data recorded
}
std::向量记录;
WSABUF缓冲区;
/*
WSASend函数导致uu WSASend。原始WSASend函数位于_WSASend中。
*/
int WSAAPI uu WSASend(套接字s、LPWSABUF lpBuffers、DWORD dwBufferCount、LPDWORD lpNumberOfBytesSent、DWORD dwFlags、LPWSAO重叠lpOverlapped、LPWSAOOVERLAPPED_COMPLETION_例程LPCOMPLETION例程)
{
if(GetAsyncKeyState(VK_XBUTTON1)<0)//如果在调用WSASend时按下鼠标侧键,则将缓冲区数据写入我的字符串数组
{
记录。向后放置(lpBuffers->buf);
/*
按住鼠标按钮时,游戏会认为数据已发送,因为*lpNumberOfBytesSent=lpBuffers->len;这是游戏发送新数据所必需的。
*/
*lpNumberOfBytesSent=lpBuffers->len;
返回0;
}
/*我需要延迟发送数据,但我无法使用Sleep()函数,因为WSASend和WSARecv在同一个线程上。由于游戏只返回0(不设置*lpnumberofybytessent=lpBuffers->len),所以我决定利用这一点*/
if(records.size()>0)
{
buffer.buf=&记录[0][0];
buffer.len=记录[0]。长度();
_WSASend(s,&缓冲区,1,0,0,0);
records.erase(records.begin());
/*没有延迟,因为我决定检查它是否工作。事实证明,它工作,但很少。当保存的数据很小时-50到50,一切都会正常,但当有很多时,它总是从服务器启动,并伴有数据读取错误*/
return 0;//我正在返回0,但没有设置*lpNumberOfBytesSent=lpBuffers->len;,因此游戏会使用相同的数据再次调用相同的函数,以发送下一个记录的缓冲区数据
}
返回_WSASend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionRoutine);//当没有记录数据时
}

以正确的顺序(从第一次记录到最后一次)写入和发送数据非常重要,因为游戏双方都使用加密+计数器。从理论上讲,如果你写得正确,并按正确的顺序发送,然后允许游戏继续发送未记录的数据,那么一切都应该正常。但正如我所说,有时它可以处理小数据,但不能处理大数据。由于读取错误,我被从服务器抛出。

我发现您的代码存在多个问题

  • 当鼠标按钮按下时,将调用方的新数据添加到列表中时,将完全忽略
    WSASend()
    dwBufferCount
    参数。如果调用者试图一次发送多个
    WSABUF
    s,您将丢失数据

  • 您根本没有将
    lpBuffers->len
    保存到列表中,您假设
    lpBuffers->buf
    是一个以null结尾的字符串,99.99999%的情况下很可能不是这样。因此,发送列表的代码无法知道给
    \u WSASend()
    的正确长度

  • 发送列表中的数据时,您完全忽略了
    \u WSASend()
    的输出

  • 当鼠标按钮未按下时,如果列表不是空的,则只发送列表中的第一条记录,并完全忽略调用者的新数据,从而永远丢失它。您需要:

    • 如果调用
      \u WSASend()
      后列表不是空的,请将调用者的新数据追加到列表的末尾

    • 发送列表中的所有内容,然后将调用者的新数据提供给
      \u WSASend()

话虽如此,请尝试以下方式:

int WSAAPI\uuu WSASend(套接字s、LPWSABUF lpBuffers、DWORD dwBufferCount、LPDWORD lpNumberOfBytesSent、DWORD dwFlags、LPWSAOOVERLAPPED lpOverlapped、LPWSAOOVERLAPPED_COMPLETION_例程)
{
*lpNumberOfBytesSent=0;
if(GetAsyncKeyState(VK_XBUTTON1)<0)
{
对于(DWORD i=0;i
或者这个:

int WSAAPI\uuu WSASend(套接字s、LPWSABUF lpBuffers、DWORD dwBufferCount、LPDWORD lpNumberOfBytesSent、DWORD dwFlags、LPWSAOOVERLAPPED lpOverlapped、LPWSAOOVERLAPPED_COMPLETION_例程)
{
*lpNumberOfBytesSent=0;
if(GetAsyncKeyState(VK_XBUTTON1)<0)
{
对于(DWORD i=0;i