结构和线程DWORD WINAPI

时间:2012-04-18 15:31:55

标签: sockets visual-c++ struct dword

什么样的家伙,希望你没事! 好吧,问题是我正在做一个聊天客户端/服务器应用程序,但是对服务器做了一些测试,我发现我在发送消息时遇到了问题。我使用了struct,socket和DWORD WINAPI线程...... 所以结构中的代码是:

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

 const char *messageServEnv;

}MESSAGE, *SMESSAGES;

然后在main方法中我调用struct来使用const char messageServEnv,一个HeapAlloc为要发送消息的线程提供一些内存,以及一个用于存储消息的char变量

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

在main方法中,我要求用户插入他想要发送的消息,我使用struct来存储消息并将其作为参数发送给线程:

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;
}

- 编辑 - 我使用Remy的解决方案解决了很多问题,但也许我错过了一些东西......在Thread threadSendMessages(SMESSAGES lpMessage)中

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

我得到并且错误说消息是未分解的,然后,我改为:

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

现在我可以使用消息和结构值 messageServEnv 但是如果我开始调试visual studio并且我尝试发送消息,则会收到错误消息使用消息而不进行初始化,然后将该部分更改为

SMESSAGES messages = new MESSAGE;

现在我可以向客户端发送消息,但只发送字符和垃圾代码

1 个答案:

答案 0 :(得分:0)

你需要为每个消息的字符串数据动态分配内存,然后在完成发送后让线程释放内存。

您还将错误的指针传递给lpParameter的{​​{1}}参数,您正在传递CreateThread()缓冲区而不是已分配的char[]结构。

您在调用MESSAGE时也使用sizeof()。由于send()messageServEnv指针,char*将返回4(32位)或8(64位),而不是指向的字符串的实际大小。

我建议将sizeof()缓冲区直接移到结构中,而不是使用指向外部缓冲区的指针,例如:

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; } 代替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;