所以,我正在编写一个小型 winsock 应用程序,我需要制作一个多客户端服务器。 我决定为每个新连接使用线程,问题是我不知道如何将多个数据传递给一个线程,所以我使用 struct。
结构:
typedef struct s_par {
char lttr;
SOCKET clientSocket;
} par;
_stdcall:
unsigned __stdcall ClientSession(void *data) {
par param = data;
char ch = param.lttr;
SOCKET clntSocket = param.clientSocket;
// ..working with client
}
主要内容:
int main() {
unsigned seed = time (0);
srand(seed);
/*
..........
*/
SOCKET clientSockets[nMaxClients-1];
char ch = 'a' + rand()%26;
while(true) {
cout << "Waiting for clients(MAX " << nMaxClients << "." << endl;
while ((clientSockets[nClient] = accept(soketas, NULL, NULL))&&(nClient < nMaxClients)) {
par param;
// Create a new thread for the accepted client (also pass the accepted client socket).
if(clientSockets[nClient] == INVALID_SOCKET) {
cout << "bla bla" << endl;
exit(1);
}
cout << "Succesfull connection." << endl;
param.clientSocket = clientSockets[nClient];
param.lttr = ch;
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, ¶m, 0, &threadID);
nClient++;
}
问题是我在数据类型转换时遇到错误。也许有人可以建议通过将此结构传递给线程来轻松修复?
最佳答案
在你的每一轮 while
循环中,你都在做两个不明智的事件:
- 传递将在循环的每个循环中销毁的自动变量的地址。
- 泄漏从
_beginthreadex
返回的线程HANDLE
这两个都不好。理想情况下,您的线程过程应该如下所示:
unsigned __stdcall ClientSession(void *data)
{
par * param = reinterpret_cast<par*>(data);
char ch = param->lttr;
SOCKET clntSocket = param->clientSocket;
// ..working with client
delete param;
return 0U;
}
调用方应该做这样的事情:
par *param = new par;
param->clientSocket = clientSockets[nClient];
param->lttr = ch;
...
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, param, 0, &threadID);
if (hThread != NULL)
CloseHandle(hThread);
else
delete param; // probably report error here as well
这应该足以让您继续前进。我建议您不妨花一些时间来了解 C++11 Threading Model .它使其中的大部分变得更加优雅(和便携!)。
祝你好运。
关于c++ - 如何将结构传递给新线程 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29188737/