首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Struct和Thread DWORD WINAPI

Struct和Thread DWORD WINAPI
EN

Stack Overflow用户
提问于 2012-04-18 15:31:54
回答 1查看 1.6K关注 0票数 0

你们好啊,希望你们没事!问题是,我正在做一个聊天客户机/服务器应用程序,但是在服务器上做一些测试,我发现我在发送消息时遇到了问题。我使用的是结构、套接字和DWORD WINAPI线程.因此,结构中的代码是:

代码语言:javascript
运行
复制
DWORD WINAPI threadSendMessages(LPVOID vpParam); //THREAD
typedef struct messagesServerChat{ //STRUCT

 const char *messageServEnv;

}MESSAGE, *SMESSAGES;

然后,在主方法中,我调用结构来使用const,一个HeapAlloc将一些内存分配给将要发送消息的线程,以及一个用于存储消息的char变量。

代码语言:javascript
运行
复制
char mServer[1024] = ""; //variable to pre-store the message
SMESSAGES messages; //call the struct
messages  = (SMESSAGES) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MESSAGE));

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

代码语言:javascript
运行
复制
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);

最后是线程代码函数。

代码语言:javascript
运行
复制
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;
}

-编辑--我用雷米的解决方案解决了很多问题,但也许我遗漏了什么.在线程threadSendMessages(SMESSAGES lpMessage)中

代码语言:javascript
运行
复制
char *ptr = messages->messageServEnv;
int len = strlen(messages->messageServEnv);

我得到和错误的消息是不可定义的,然后,我更改为:

代码语言:javascript
运行
复制
SMESSAGES messages;
char *ptr = messages->messageServEnv;
int len = strlen(messages->messageServEnv);

现在我可以使用消息和结构值messageServEnv,但是如果我开始调试visual studio并尝试发送一条消息,我会得到一个错误,即消息是在未初始化的情况下使用的,然后我将该部分更改为

代码语言:javascript
运行
复制
SMESSAGES messages = new MESSAGE;

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-18 20:54:13

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

您还传递了指向lpParameter参数CreateThread()的错误指针,您传递的是char[]缓冲区而不是已分配的MESSAGE结构。

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

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

代码语言:javascript
运行
复制
typedef struct messagesServerChat
{
    char messageServEnv[1024]; 
}
MESSAGE, *SMESSAGES; 

DWORD WINAPI threadSendMessages(SMESSAGES lpMessage);

代码语言:javascript
运行
复制
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;

代码语言:javascript
运行
复制
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[]

代码语言:javascript
运行
复制
typedef struct messagesServerChat
{
    std::string messageServEnv; 
}
MESSAGE, *SMESSAGES; 

DWORD WINAPI threadSendMessages(SMESSAGES lpMessage);

代码语言:javascript
运行
复制
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;

代码语言:javascript
运行
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10212785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档