什么样的家伙,希望你没事! 好吧,问题是我正在做一个聊天客户端/服务器应用程序,但是对服务器做了一些测试,我发现我在发送消息时遇到了问题。我使用了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;
现在我可以向客户端发送消息,但只发送字符和垃圾代码
答案 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;