2012-04-18 1 views
0

Что случилось, ребята, надеюсь, вы в порядке! , проблема в том, что я делаю приложение клиент/сервер чата, но выполняю некоторые тесты с сервером, я узнал, что у меня проблема с отправкой сообщений. Я использую на структуру, розетку и DWORD WINAPI тему ... Поэтому код в структурах является:Struct and Thread DWORD WINAPI

DWORD WINAPI threadSendMessages(LPVOID vpParam); //THREAD 
typedef struct messagesServerChat{ //STRUCT 

const char *messageServEnv; 

}MESSAGE, *SMESSAGES; 

затем в основном методе я называю структуру использовать константный обугленный messageServEnv, HeapAlloc к дать некоторую память к потоку, который собирается отправить сообщение и переменный обугленный, которую я использую, чтобы сохранить сообщение

char mServer[1024] = ""; //variable to pre-store the message 
SMESSAGES messages; //call the struct 
messages = (SMESSAGES) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MESSAGE)); 

в основном методе, я прошу пользователь вставить сообщение, которое он хочет отправить и Я использую структуру для хранения сообщения и отправляю его в поток в качестве параметра:

cout<<"Dear user, please insert your message: "; 

setbuf(stdin, NULL); 
fgets(mServer, 1024, stdin); 
messages->messageServEnv = mServer; 
DWORD hSend; //send the parameters to the thread function 
HANDLE sendThread = CreateThread(0, 0, threadSendMessages, mServer, 0, &hSend); 

и, наконец, код функции резьбы

DWORD WINAPI threadSendMessages(LPVOID lpParam){ 

SMESSAGES messages; 
messages = (SMESSAGES)lpParam; 
int mesa; 
mesa = send(sConnect, (char *)messages->messageServEnv, sizeof messages->messageServEnv, 0); 
//sConnect is the socket 
//messages = to use the struct, and messageServEnv is the struct data that should contain the message 
return 0; 
} 

--Edit-- исправить много проблем, используя решение Реми, но, может быть, я что-то ... в threadSendMessages темы отсутствует (SMESSAGES lpMessage)

char *ptr = messages->messageServEnv; 
int len = strlen(messages->messageServEnv); 

я получаю и ошибка, которая говорит, что сообщения в undifined, то я изменил:

SMESSAGES messages; 
char *ptr = messages->messageServEnv; 
int len = strlen(messages->messageServEnv); 

теперь я могу использовать сообщения и значение структуры messageServEnv но если я начало отладки Visual Studio и я пытаюсь отправить сообщение, я получаю сообщение об ошибке: сообщений используются без инициализации, то я изменю эту часть в

SMESSAGES messages = new MESSAGE; 

и теперь я могу отправлять сообщения клиента, но только символы и замусоривание код

+0

Что касается редактирования, см. Мой обновленный ответ. –

ответ

0

Вы должны динамически выделять память для данных строки каждого сообщения, и затем нити освободить память после завершения его отправки ,

Вы также передавая неправильный указатель на параметр CreateThread()lpParameter, вы передаете свой char[] буфер вместо вашей выделенных MESSAGE структуры.

Вы также используете sizeof() при звонке send(). Так как ваш messageServEnv является указателем char*, sizeof() вернет 4 (32-разрядные) или 8 (64-разрядные) вместо фактического размера строки, на которую указывают.

Я хотел бы предложить перемещение char[] буфера непосредственно в структуры вместо того, чтобы использовать указатель на внешний буфер, например:

typedef struct messagesServerChat 
{ 
    char messageServEnv[1024]; 
} 
MESSAGE, *SMESSAGES; 

DWORD WINAPI threadSendMessages(SMESSAGES lpMessage); 

.

cout << "Dear user, please insert your message: "; 
setbuf(stdin, NULL); 

SMESSAGES message = new MESSAGE; 
fgets(message->messageServEnv, sizeof(message->messageServEnv), stdin); 

DWORD hSend; 
HANDLE sendThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&threadSendMessages, message, 0, &hSend); 
if (!sendThread) 
    delete message; 

.

DWORD WINAPI threadSendMessages(SMESSAGES lpMessage) 
{ 
    // send() is not guaranteed to send the entire message 
    // in one go, so call it in a loop... 

    char *ptr = lpMessage->messageServEnv; 
    int len = strlen(lpMessage->messageServEnv); // or sizeof() if you really want to send all 1024 bytes instead 

    while (len > 0) 
    { 
     int mesa = send(sConnect, ptr, len, 0); 
     if (mesa > 0) 
     { 
      ptr += mesa; 
      len -= mesa; 
      continue; 
     } 

     // this is only needed if you are using a non-blocking socket... 
     if ((mesa == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK)) 
     { 
      fd_set fd; 
      FD_ZERO(&fd); 
      FD_SET(sConnect, &fd); 

      timeval tv; 
      tv.tv_sec = 5; 
      tv.tv_usec = 0; 

      if (select(0, NULL, &fd, NULL, &tv) > 0) 
       continue; 
     } 

     ... error handling ... 
     break; 
    } 

    delete message; 
    return 0; 
} 

Если вы хотите передать динамически lengthed строку вместо этого, вы лучше использовать std::string вместо char[]:

typedef struct messagesServerChat 
{ 
    std::string messageServEnv; 
} 
MESSAGE, *SMESSAGES; 

DWORD WINAPI threadSendMessages(SMESSAGES lpMessage); 

.

cout << "Dear user, please insert your message: "; 
setbuf(stdin, NULL); 

SMESSAGES message = new MESSAGE; 
getline(stdin, message->messageServEnv); 

DWORD hSend; 
HANDLE sendThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&threadSendMessages, message, 0, &hSend); 
if (!sendThread) 
    delete message; 

.

DWORD WINAPI threadSendMessages(SMESSAGES lpMessage) 
{ 
    // send() is not guaranteed to send the entire message 
    // in one go, so call it in a loop... 

    char *ptr = lpMessage->messageServEnv.c_str(); 
    int len = lpMessage->messageServEnv.length(); // or sizeof() if you really want to send all 1024 bytes instead 

    while (len > 0) 
    { 
     int mesa = send(sConnect, ptr, len, 0); 
     if (mesa > 0) 
     { 
      ptr += mesa; 
      len -= mesa; 
      continue; 
     } 

     // this is only needed if you are using a non-blocking socket... 
     if ((mesa == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK)) 
     { 
      fd_set fd; 
      FD_ZERO(&fd); 
      FD_SET(sConnect, &fd); 

      timeval tv; 
      tv.tv_sec = 5; 
      tv.tv_usec = 0; 

      if (select(0, NULL, &fd, NULL, &tv) > 0) 
       continue; 
     } 

     ... error handling ... 
     break; 
    } 

    delete message; 
    return 0; 
} 
+0

какая ошибка? Вы должны быть более конкретными. Пожалуйста, не помещайте столько кода в комментарий, вместо этого редактируйте исходный вопрос. –

+0

жаль, что я отправляю новый вопрос, используя комментарий, я редактировал исходный вопрос с новой ошибкой, я знаю, что я что-то пропускаю в коде, потому что я могу отправлять сообщения, но только код мусора и некоторые символы – Adrian87

+0

Я исправил ошибки, в моем коде были опечатки. –

 Смежные вопросы

  • Нет связанных вопросов^_^