2017-02-25 75 views
-1

即時通訊目前正在努力學習插座和線程是如何工作的,爲此,我開始編寫一個程序來做出某種聊天室:C++:可以T獲得插座,線程和結構工作

#include <iostream> 
#include <windows.h> 
#include <process.h> 
#include <winsock2.h> 
#include <vector> 

using namespace std; 

struct par { 
    SOCKET* s; 
    string* buffer; 
    bool keep = 1; 
}; 

struct HANDLES { 
    HANDLE hRecv; 
    HANDLE hSend; 
}; 

unsigned int WINAPI recvThread(LPVOID param) { 
    par* data = (par*)param; 
    char* inBuf; 
    unsigned short int inSize; 
    string aux = inBuf; 
    string* auxptr = data->buffer; 
    SOCKET* s = data->s; 
    while(true) { 
     inSize = recv(*s, inBuf, 2000, 0); 
     inBuf[inSize] = '\0'; 
     *auxptr = aux; // ??? 
    } 
} 

unsigned int WINAPI sendThread(LPVOID param) { 
    par* data = (par*)param; 
    string auxBuf = "NULL"; 
    string* auxptr = data->buffer; 
    SOCKET* s = data->s; 
    while (true) { 
     if(auxBuf != (*auxptr)) { 
      string auxstring = *auxptr; 
      const char* auxchar = auxstring.c_str(); 
      send(*s, auxchar, strlen(auxchar), 0); 
      auxBuf = auxstring; 
     } 
     Sleep(200); 
    } 
} 

int main() 
{ 
    WSADATA wsa; 
    WSAStartup(MAKEWORD(2,2), &wsa); 
    string buf = "NULL"; 
    vector<HANDLES> hVec; 

    SOCKET s; 
    s = socket(AF_INET, SOCK_STREAM, 0); 

    sockaddr_in server; 

    server.sin_family = AF_INET; 
    server.sin_port = htons(8888); 
    server.sin_addr.s_addr = INADDR_ANY; 

    bind(s, (sockaddr*)&server, sizeof(server)); 

    listen(s, 5); 

    sockaddr_in clientdir; 
    int siz = sizeof(clientdir); 
    SOCKET cliente; 
    while((cliente = accept(s, (sockaddr*)&clientdir, &siz))) { 
     par* newParams; 
     newParams->s = &cliente; 
     newParams->buffer = &buf; 
     if(cliente != INVALID_SOCKET) { 
      HANDLES aux; 
      aux.hRecv = (HANDLE)_beginthreadex(NULL, 0, recvThread, (void*)newParams, 0, 0); 
      aux.hSend = (HANDLE)_beginthreadex(NULL, 0, sendThread, (void*)newParams, 0, 0); 
      hVec.push_back(aux); 
     } 
    } 
} 

遇到的第一個問題出現在:newParams-> s =&cliente; 使服務器崩潰。 如果有人能告訴我我做錯了什麼以及應該實施的其他修復,我將不勝感激。

+0

'newParams'沒有初始化,因此你不能在下一行'newParams-> s'中使用它...下一次,請 - 附上你收到的錯誤 – ymz

回答

0

第一個問題是您有一個未初始化的指針(newParams),指向任何地方有效。這然後您使用,那將導致未定義的行爲

當修復以上(通過與new分配新par結構和指向newParams到該對象),必須另一個問題:該指針在結構中SOCKETstring成員。所有的指針,沒有多少(或少數)連接和線程都將指向相同SOCKETstring

如果接收和發送線程應該共享SOCKETstring然後代替具有這些成員是指針,它們是被複製作爲或在需要時的值,但該線程共享結構,這是通過使解決指向兩個線程的指針都是相同的newParams

還有更多未初始化指針的問題,以及數據競爭(因爲您不保護線程共享資源)。

我的建議是採取幾個步驟,並廢除全部您的代碼。然後重新編碼,同時採取小嬰兒步驟,一次添加一點點,同時確保它的工作,並且你明白它如何它的工作原理。 Rubber-duck debugging以及使用實際的調試器極大地幫助。並閱讀書籍。練習。不要急於嘗試立即做所有事情。

+0

謝謝,糾正了指針錯誤和接受了你的建議,並刮掉了代碼。現在它正在工作。 –