我不是那么合格的C++编程,但我真的不能通过这个问题.我的项目如下:连接到WIFI服务器与TCP协议.服务器不断发送文本行:没问题。它系统地连接。一个专用的线程正在循环接收文本并在编辑窗口中显示它。当我点击“断开连接”时,它应该会终止按钮。但是我不能点击那个按钮,因为我得到一条消息(Cancel,Cancel,Ignore),告诉我Abort()已经被调用。同时,消息仍然显示,并行调试窗口向我显示线程正在正常工作。
这是我的WndProc的代码:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ACTIVATEAPP:
{ Create_incoming_NMEA_messages_box();
Create_info_message_box();
Create_push_button();
}
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDC_MAIN_BUTTON: // connect - disconnect
{
if (!Connected)
{
if (Connect_addr(szServer, szPort) == 0) // == 0 => connected
{
Connected = true;
SendMessage(hEditOut, WM_SETTEXT, NULL, (LPARAM)"Connected at Host = 10.0.0.1 / Port = 10111");
Button_SetText(hWndButton, "Disconnect");
thread TCPThread(Loop_while_connected); // thread constructed and launched
}
}
else {
Connected = false;
SendMessage(hEditOut, WM_SETTEXT, NULL, (LPARAM)"Disconnected");
//TCPThread.join();
Button_SetText(hWndButton, "Connect");
}
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Connect_addr(szServer,szPort)函数如下所示:
int Connect_addr(char* host, char* port)
{
// Set up Winsock INITIALIZATION
WSADATA WsaDat;
int nResult = WSAStartup(MAKEWORD(2, 2), &WsaDat);
if (nResult != 0)
{
MessageBox(hWnd, "Winsock initialization failed", "Critical Error", MB_ICONERROR);
SendMessage(hWnd, WM_DESTROY, NULL, NULL);
}
struct addrinfo hints; // defines address type
struct addrinfo* result, * rp;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // Allow IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP socket
hints.ai_flags = 0;
hints.ai_protocol = IPPROTO_TCP;
int s = getaddrinfo(host, port, &hints, &result);
// getaddrinfo() returns a list of address structures.
// Try each address until we successfully connect(x). x = socket ID
// If socket(x) (or connect(x)) fails, we (close the socket
// and) try the next address.
int resconn = -1; // result of the connection attempt
for (rp = result; rp != NULL; rp = rp->ai_next) // rp = pointer to the chained list of all IP addresses managed by the client machine
{
ConnectSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (ConnectSocket == -1)
continue;
resconn = connect(ConnectSocket, rp->ai_addr, rp->ai_addrlen);
if (resconn == -1)
{
resconn = WSAGetLastError();
MessageBox(0, "Non connect\u00E9", "Erreur connexion", MB_ABORTRETRYIGNORE);
}
else break; // Success
}
freeaddrinfo(result); // No longer needed
return resconn;
}
这个函数工作正常。问题似乎与WindProc代码中的线程TCPThread(Loop_while_connected)有关(case IDC_MAIN_BUTTON)。
这里的线程函数是Loop_while_connected:
const unsigned HISTORY_BUFF_SIZE = 1000000;
char szHistory[HISTORY_BUFF_SIZE] = { 0 }; // NMEA messages accumulating buffer
int nKr = 0; // sums the received Kr to reset szHistory to start before saturating the buffer
const unsigned int Buff_Size = 10240;
void Loop_while_connected()
{
int inDataLength = 0;
if (Connected)
do
{
char szIncoming[Buff_Size];
ZeroMemory(szIncoming, Buff_Size);
inDataLength = 0;
inDataLength = recv(ConnectSocket, szIncoming, Buff_Size, 0);
if (inDataLength > 0)
{
strncat_s(szHistory, _countof(szHistory), szIncoming, inDataLength);
nKr += inDataLength;
SendMessage(hEditIn, WM_SETTEXT, sizeof(szIncoming) - 1, reinterpret_cast<LPARAM>(szHistory));
PostMessage(hEditIn, EM_SETSEL, 0, -1); // Select all
PostMessage(hEditIn, EM_SETSEL, -1, -1); // Unselect and stay at the end pos
PostMessage(hEditIn, EM_SCROLLCARET, 0, 0); // Set scrollcaret to the current Pos
}
if (nKr >= HISTORY_BUFF_SIZE - Buff_Size) {
ZeroMemory(szHistory, sizeof(szHistory));
nKr = 0;
}
} while (Connected);
}
开始是这样的:
enter image description here
当我点击连接时,它会连接,但会发出这样的错误消息,而文本总是滚动:
enter image description here
现在,如果我按下“Debug to debug”,线程实际上会停止,并且在析构过程结束时,我会得到一个调试窗口,显示一个错误。
enter image description here
我肯定在某个地方做了一些愚蠢的事情。我已经检查了我的线程在启动时是可连接的,但我仍然不明白为什么我在WndProc过程中对TCPThread.join()的调用在断开连接时被编译器拒绝。也许这两个问题是相关的?谢谢你的帮助。
1条答案
按热度按时间jtoj6r0c1#
事实上,没有什么是愚蠢的。Microsoft VC++ Win32似乎不符合C++ 11多线程的“简单性”(构造函数/析构函数)。
编译没有问题,但最终在运行时出现错误。
解决方案是像这样使用_thread
假设函数Loop_while_connected通过在其头部传递一个指向线程ID的指针作为参数来呈现与_cloud线程的调用一致,如下所示: