2014-09-24 199 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