cumulonimbus 发表于 2023-7-8 21:10:00

一个聊天程序,为什么我的代码运行到这就中止了。

BOOL CChatDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

        // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
        //执行此操作
        SetIcon(m_hIcon, TRUE);                        // 设置大图标
        SetIcon(m_hIcon, FALSE);                // 设置小图标

        // TODO:在此添加额外的初始化代码
        InitSocket();
        RECVPARAM *pRevcParam = new RECVPARAM;
        pRevcParam->socket = m_Socket;
        pRevcParam->hwnd = m_hWnd;
        HANDLE hThread = CreateThread(NULL, 0, RecvProc, (LPVOID)pRevcParam, 0, NULL);
        CloseHandle(hThread);
        return TRUE;// 除非将焦点设置到控件,否则返回 TRUE
}


DWORD WINAPI CChatDlg::RecvProc(LPVOID lpParameter)
{
      SOCKET socket = ((RECVPARAM*)lpParameter)->socket;
      HWND hwnd = ((RECVPARAM*)lpParameter)->hwnd;

      SOCKADDR_IN addrFrom;
      int len = sizeof(SOCKADDR);

      char recvBuf;
      char tempBuf;
      int retVal;
      while (TRUE)
      {
                retVal = recvfrom(socket, recvBuf, 200, 0, (SOCKADDR*)&addrFrom, &len);                        //运行不下去了
                if (SOCKET_ERROR == retVal)
                {
                        break;
                }
                sprintf(tempBuf, "%s说:%s", inet_ntoa(addrFrom.sin_addr), recvBuf);
                ::PostMessage(hwnd, WM_RECVDATA, 0, (LPARAM)tempBuf);
      }
      return 0;
}

陶远航 发表于 2023-7-8 21:11:17

我看到您提供了一段C++代码,这是一个聊天程序的一部分。根据您的描述,代码在某个地方中止了。我会尝试帮助您找到可能的问题。

首先,我为代码排版以便更容易阅读:

BOOL CChatDlg::OnInitDialog() {
    CDialog::OnInitDialog();

    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, FALSE);

    InitSocket();
    RECVPARAM *pRevcParam = new RECVPARAM;
    pRevcParam->socket = m_Socket;
    pRevcParam->hwnd = m_hWnd;

    HANDLE hThread = CreateThread(NULL, 0, RecvProc, (LPVOID)pRevcParam, 0, NULL);
    CloseHandle(hThread);

    return TRUE;
}

DWORD WINAPI CChatDlg::RecvProc(LPVOID lpParameter) {
    SOCKET socket = ((RECVPARAM*)lpParameter)->socket;
    HWND hwnd = ((RECVPARAM*)lpParameter)->hwnd;
    SOCKADDR_IN addrFrom;
    int len = sizeof(SOCKADDR);
    char recvBuf;
    char tempBuf;
    int retVal;

    while (TRUE) {
      retVal = recvfrom(socket, recvBuf, 200, 0, (SOCKADDR*)&addrFrom, &len);

      if (SOCKET_ERROR == retVal) {
            break;
      }

      sprintf(tempBuf, "%s说:%s", inet_ntoa(addrFrom.sin_addr), recvBuf);
      ::PostMessage(hwnd, WM_RECVDATA, 0, (LPARAM)tempBuf);
    }

    return 0;
}


代码中有一个可能的问题是在 RecvProc 函数的 recvfrom 调用。如果 recvfrom 返回 SOCKET_ERROR ,这意味着在接收数据时发生了错误。这可能导致代码"运行不下去了",也就是您所描述的问题。但是,在这种情况下,代码应该会跳出循环并正常结束线程。

一个可能的原因是 WSAGetLastError() 返回的错误码。在调试过程中,您可以在 recvfrom 调用失败时检查此错误码:

if (SOCKET_ERROR == retVal) {
    int errCode = WSAGetLastError();
    // 这里可以输出或记录错误码,以便进一步分析
    break;
}


检查 WSAGetLastError() 返回的错误码可以帮助您找到问题的根本原因。这可能是由于初始化Winsock库的问题、套接字创建问题、套接字选项设置问题等。

请注意,我无法看到您的完整代码,包括 InitSocket() 函数和 RECVPARAM 结构的定义。因此,这里的建议可能无法解决您的问题。如果您需要进一步的帮助,请提供更多的上下文或代码,以便我能更好地理解您的问题。

isdkz 发表于 2023-7-8 21:12:25

你的代码运行到recvfrom函数处时可能会因为几个原因停止运行:

1. 网络问题:如果没有网络连接或者网络连接不稳定, recvfrom函数可能会因为无法从指定的socket接收数据而阻塞或失败。

2. 阻塞式socket:默认情况下,Windows sockets是阻塞的。这意味着 recvfrom 函数会阻塞,直到它接收到一些数据。如果没有任何数据发送到这个socket,那么这个函数可能会无限期地阻塞。你可能需要查看socket是否已经准备好接收数据,或者设置socket为非阻塞模式。

3. 错误的socket句柄:如果你传给 recvfrom 的socket句柄无效(例如,它已经被关闭),那么这个函数将返回SOCKET_ERROR。

4. 缓冲区溢出:在 recvBuf 定义为200字节,如果从socket接收的数据大于这个大小,可能会导致溢出问题。这不一定会导致程序停止,但可能会引发其他问题,如未定义的行为或数据损坏。

你可以使用WSAGetLastError函数来获取具体的错误信息。此函数会返回上一次socket操作失败的原因。可以帮助你了解为什么recvfrom函数失败。

例如:

retVal = recvfrom(socket, recvBuf, 200, 0, (SOCKADDR*)&addrFrom, &len);
if (SOCKET_ERROR == retVal)
{
    int error_code = WSAGetLastError();
    printf("recvfrom failed with error code : %d\n", error_code);
    break;
}

这样你就可以得到更具体的错误代码,然后查阅相关资料进行解决。

编程追风梦 发表于 2023-7-9 07:01:37

根据你提供的代码片段,有几个可能导致程序中止的原因:

1. `InitSocket()` 函数:在 `CChatDlg::OnInitDialog()` 函数中调用了 `InitSocket()` 函数。如果 `InitSocket()` 函数存在问题,可能导致后续的代码无法正常执行。请确保 `InitSocket()` 函数正确初始化了网络套接字,并没有引发任何错误。

2. `CreateThread()` 函数:在 `CChatDlg::OnInitDialog()` 函数中创建了一个线程,调用了 `RecvProc` 函数作为线程函数。如果在创建线程时出现问题,可能导致程序中止。请确保 `CreateThread()` 函数成功创建了线程,并返回了有效的句柄。

3. `RecvProc` 函数:`RecvProc` 函数是作为线程函数在独立线程中执行的。如果在 `recvfrom()` 函数调用时发生错误,可能导致函数中止。请确保网络套接字正确设置,并且能够接收到数据。

在调试这段代码时,你可以尝试以下几个步骤来定位问题:

1. 确保网络套接字的初始化(`InitSocket()`)正确执行,并且没有返回错误代码。你可以检查相关的初始化代码,例如创建套接字、绑定地址等。

2. 检查线程的创建(`CreateThread()`)是否成功,并返回了有效的句柄。你可以在创建线程后,检查 `hThread` 的值是否为有效句柄。

3. 检查 `RecvProc` 函数中的 `recvfrom()` 调用是否正确,并且能够接收到数据。你可以添加调试输出或日志语句,观察程序是否能够进入 `RecvProc` 函数,并在调用 `recvfrom()` 时接收到数据。

4. 检查是否有其他可能导致程序中止的因素。例如,确保程序的消息循环正常运行,正确处理消息等。

如果问题仍然存在,建议提供更多详细的错误信息、调试输出或完整的代码,以便更好地帮助你解决问题。

cumulonimbus 发表于 2023-7-10 21:13:04

陶远航 发表于 2023-7-8 21:11
我看到您提供了一段C++代码,这是一个聊天程序的一部分。根据您的描述,代码在某个地方中止了。我会尝试帮 ...

不是这样的,是在程序开始运行时就发生的,代码到那就不往下运行了,而是直接跳出,生成对话框程序

可惜我上传不了附件。

cumulonimbus 发表于 2023-7-10 21:13:41

isdkz 发表于 2023-7-8 21:12
你的代码运行到recvfrom函数处时可能会因为几个原因停止运行:

1. 网络问题:如果没有网络连接或者 ...

不是这样的,是在程序开始运行时就发生的,代码到那就不往下运行了,而是直接跳出,生成对话框程序

可惜我上传不了附件。

cumulonimbus 发表于 2023-7-10 21:15:01

编程追风梦 发表于 2023-7-9 07:01
根据你提供的代码片段,有几个可能导致程序中止的原因:

1. `InitSocket()` 函数:在 `CChatDlg::OnInit ...

不是这样的,是在程序开始运行时就发生的,代码到那就不往下运行了,而是直接跳出,生成对话框程序

可惜我上传不了附件。

陶远航 发表于 2023-7-10 21:35:23

cumulonimbus 发表于 2023-7-10 21:13
不是这样的,是在程序开始运行时就发生的,代码到那就不往下运行了,而是直接跳出,生成对话框程序

可 ...

了解您的问题。如果在运行时代码直接跳出,并且没有执行RecvProc函数的循环,那么可能的原因是在CreateThread创建线程时发生了问题。在这种情况下,我们需要检查CreateThread的返回值以获取更多信息。

以下是如何检查CreateThread的返回值:
HANDLE hThread = CreateThread(NULL, 0, RecvProc, (LPVOID)pRevcParam, 0, NULL);
if (hThread == NULL) {
    DWORD dwError = GetLastError();
    // 这里可以输出或记录错误码,以便进一步分析
} else {
    CloseHandle(hThread);
}
如果CreateThread返回NULL,那么代表线程创建失败。您可以检查GetLastError()函数的返回值以获取更多关于失败原因的信息。

另外,您也可以尝试使用C++标准库中的std::thread来替换CreateThread。这将使代码更具可移植性,并减少与Win32 API相关的潜在问题。以下是使用std::thread的示例:
#include <thread>

// ...其他代码...

void CChatDlg::RecvProc(RECVPARAM* pRevcParam) {
    // ...和原来的RecvProc函数一样...
}

// ...其他代码...

BOOL CChatDlg::OnInitDialog() {
    // ...其他初始化代码...

    std::thread recvThread(&CChatDlg::RecvProc, this, pRevcParam);
    recvThread.detach(); // 与主线程分离,允许子线程独立运行

    return TRUE;
}
请注意,使用std::thread可能需要对代码进行一些调整,例如将RecvProc的签名从DWORD WINAPI RecvProc(LPVOID)更改为void RecvProc(RECVPARAM*)。

如果这些建议仍无法解决问题,请提供更多的代码和上下文,以便我能更好地理解您的问题。

cumulonimbus 发表于 2023-7-11 13:40:48

陶远航 发表于 2023-7-10 21:35
了解您的问题。如果在运行时代码直接跳出,并且没有执行RecvProc函数的循环,那么可能的原因是在CreateTh ...

谢谢,很有帮助,我会仔细检查一下的

陶远航 发表于 2023-7-11 13:44:18

cumulonimbus 发表于 2023-7-11 13:40
谢谢,很有帮助,我会仔细检查一下的

嗯嗯,没事
页: [1]
查看完整版本: 一个聊天程序,为什么我的代码运行到这就中止了。