C ++ - ошибка CreateThread

0

Я создаю многопоточный клиентский сервер чата, используя VC++ 2012 Express. Код был адаптирован здесь: http://www.codeproject.com/Articles/14032/Chat-Client-Server

Кажется, что сервер работает нормально. Однако, как-то клиент не может запустить поток для получения сообщения. Функция GetLastError() возвращает 8 при вызове.

Вот фрагмент кода клиента:

#include "Chatter_Client.hpp"

CMessenger MessObj;
//... CMessenger::Init initializes Winsock, socket, and connection.
int CMessenger::RecMessage()
{
    char buffRetData[4096];
    int stat;

    stat = recv(conn, buffRetData, 4096, 0);
    if(stat == -1) {
        cout << "Message not received!" << endl;
        return 1; // gagal
    } else {
        cout << "-->" << buffRetData << "\n";
        return 0; // looping lagi~
    }
}

DWORD WINAPI MessageRecThread(LPVOID pParam)
{
    for(;;) {
        Sleep(50);
        if(MessObj.RecMessage())
            break;
    }
    return 0;
}

int main()
{
    string buf;
    DWORD RecThreadID;

    string sServerAddress;
    int iPort;
    for(;;) {
        cout << "Server address: ";
        cin >> sServerAddress;
        if (sServerAddress.size() == 0) {
            cout << "No Address entered!" << endl;
        } else break;
    }
    cout << "Server port: ";
    cin >> iPort;

    MessObj.Init(sServerAddress.c_str(), iPort);
    if(!MessObj.IsConnected()) {
        cout << "Connection error!";
        _getch();
        return -1;
    }
    Sleep(30);

    HANDLE RecThread = CreateThread(NULL, 20000, MessageRecThread, NULL, 0, &RecThreadID);
    if(RecThread == NULL) {
        cout << "Listener thread cannot be created! ERROR CODE: " << GetLastError() << endl;
        _getch();
        return 1;
    } else {
        cout << "Yey masuk!" << endl;
    }
    for(;;) {
        cin >> buf;
        if(MessObj.SendMessage(buf)) {
            cout << "Connection lost!" << endl;
            break;
        }
    }
    cout << "Terminating client...";
    _getch();

    return 0;
}

и заголовок:

#include <cstdio>
#include <winsock2.h>
#include <conio.h>
#include <iostream>
#include <string>
#include <windows.h>

#pragma comment(lib, "WS2_32.lib")

using namespace std;

class CMessenger
{
public:
    CMessenger();
    ~CMessenger();
    void Init(string iIP, int iPort);
    int SendMessage(string sMessage);
    int RecMessage();
    bool IsConnected();
private:
    bool ConnStatus;
    string sIPAddress;
    int sPort;
    SOCKET conn;
};

Я попытался использовать С++ 11 <thread>, но когда был вызван класс потока, отладчик немедленно вызвал abort().

Любые подсказки?

PS: этот код компилируется.

РЕДАКТИРОВАТЬ

это фрагмент нового ::Init с некоторыми изменениями:

void CMessenger::Init(const string& iAddress, const string& iPort)
{
    // init winsock
    WSAData wsData;
    int stat = WSAStartup(MAKEWORD(2,0), &wsData);

    if (stat != 0) {
        cerr << "ERROR: WINCODE " << WSAGetLastError() << endl;
        return;
    }
    // get server info
    addrinfo hints, *res, *p_hints;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    stat = getaddrinfo(iAddress.c_str(), iPort.c_str(), &hints, &res);
    if(stat != 0) {
        cerr << "ERROR: " << gai_strerror(stat) << endl;
        return;
    }
    void *addr;
    char ipstr[INET6_ADDRSTRLEN];
    p_hints = res;
    sockaddr_in *ip = (struct sockaddr_in*)p_hints->ai_addr;
    addr = &(ip->sin_addr);

    // convert to string and print it
    inet_ntop(p_hints->ai_family, addr, ipstr, sizeof ipstr);
    cout << "Server IP: " << ipstr << endl;

    // init socket
    conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (conn == INVALID_SOCKET) {
        cout << "SOCKET ERROR\n";
        return;
    }

    // connect to server
    stat = connect(conn, res->ai_addr, res->ai_addrlen);
    if(stat != 0) {
        cerr << "ERROR: " << WSAGetLastError() << endl;
        return;
    }

    // connect OK
    sPort = atoi(iPort.c_str());
    sAddress = iAddress;
    cout << "Connection established." << endl << endl;
    ConnStatus = true;
    Sleep(30);
    return;
}

все еще проблема с потоком.

  • 0
    Если GetLastError возвращает 8, это означает «Недостаточно памяти», если это поможет.
  • 0
    Что произойдет, если вы передадите 0 для размера стека?
Показать ещё 4 комментария
Теги:
multithreading
winsock

1 ответ

2

Просто попробовал свой код, заменив отсутствующие методы на заглушки, и протекция была создана без каких-либо проблем. Убедитесь, что ваш метод MessObj :: Init() не наносит вреда (повреждение памяти).

И одно дополнение:

CMessanger
{
...
    void Init(string iIP, int iPort)
...
}


    string sServerAddress;
...
    MessObj.Init(sServerAddress.c_str(), iPort);

Это плохой стиль - для многих копий строковых объектов и string-> char * → преобразования строк. Если переданная строка не копируется в методе CMessenger :: Init(), тогда метод следует изменить на

   void Init(const string& iIP, int iPort)

и назовите его

     MessObj.Init(sServerAddress, iPort);

если строковый аргумент копируется внутри метода, вы все равно передаете аргумент по значению, но используете подвижную семантику внутри метода, например:

   void Init(string iIP, int iPort)
   {
         m_ip = std::move(iIP);
   }
  • 0
    добавила ваши предложения, но все еще с ошибкой потока. Я добавил мой :: Init () фрагмент

Ещё вопросы

Сообщество Overcoder
Наверх
Меню