我试图使用winsock制作一个简单的僵尸网络(不是出于恶意目的),客户端是正常的(至少在语法上),但是当我调用accept函数时服务器出错,它返回SOCKET_ERROR ,我调用WSAGetLastError()来获取错误号,它返回10014.在MSDN页面中,它说:
地址错误。
系统在尝试使用调用的指针参数时检测到无效指针地址。如果应用程序传递无效指针值,或者缓冲区的长度太小,则会发生此错误。例如,如果参数的长度(sockaddr结构)小于sizeof(sockaddr)。
好吧,我不知道该怎么做。
botnetserver.cpp
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#define PORT 5051
#define BUFFMAX 1024 // Buffer max
using namespace std;
int main() {
SOCKADDR_IN svaddr; // server address
SOCKADDR_IN claddr; // client addres
SOCKET listensocket;
SOCKET client;
WSADATA WsaData;
char buffer[BUFFMAX];
int i = sizeof(client);
//ShowWindow(GetConsoleWindow(), SW_HIDE);, fail
WSAStartup(MAKEWORD(2, 2), &WsaData);
listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
svaddr.sin_family = AF_INET;
svaddr.sin_port = htons(PORT);
svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listensocket, (SOCKADDR*) &svaddr, sizeof(svaddr));
client = listen(listensocket, 5)) == SOCKET_ERROR
accept(listensocket, (SOCKADDR*)&claddr, &i) // Error here
while(true) {
/* other things i tried
cout << "\n\n" << buffer << "\n\n";
cout << o << "\n";
buffer[BUFFMAX] = '\0';*/
recv(client, buffer, BUFFMAX, 0);
if(strcmp(buffer, "<fim>") != 0) {
system(buffer);
//break;
} else {break;}
}
closesocket(client);
closesocket(listensocket);
WSACleanup();
system("pause");
}
答案 0 :(得分:1)
您的代码中有两个错误:
int i = sizeof(client);
i
需要初始化为sizeof(claddr)
。这就是accept()
失败的原因。 sizeof(client)
小于sizeof(claddr)
,因此accept()
认为您的claddr
缓冲区太小而无法接收客户端的IP地址。您在引用的文档中明确说明了这一点:
系统在尝试使用调用的指针参数时检测到无效指针地址。如果应用程序传递无效指针值或缓冲区的长度太小,则会发生此错误。例如,如果参数的长度(sockaddr结构)小于sizeof(sockaddr)。
client = listen(listensocket, 5)) == SOCKET_ERROR
client
是SOCKET
句柄。您无法将==
运算符的结果分配给SOCKET
。您需要将accept()
的结果改为client
。
将这些行更改为:
int i = sizeof(claddr);
...
listen(listensocket, 5);
client = accept(listensocket, (SOCKADDR*)&claddr, &i);
话虽如此,您还需要修复recv()
循环。 recv()
不会返回以null结尾的数据,但strcmp()
需要这样做。您需要在读取后空终止缓冲区,或者使用strncmp()
代替,使用recv()
的结果作为缓冲区长度。您需要考虑到recv()
可能需要多次调用才能接收<fim>
,因此您需要实施适当的缓冲。
并且,您需要在所有函数调用上添加正确的错误处理。