C++:无法让套接字、线程和结构工作

Posted

技术标签:

【中文标题】C++:无法让套接字、线程和结构工作【英文标题】:C++: Can t get sockets, threads and structures to work 【发布时间】:2017-02-25 16:55:11 【问题描述】:

我目前正在尝试学习套接字和线程是如何工作的,为此,我开始编写一个程序来制作某种聊天室:

#include <iostream>
#include <windows.h>
#include <process.h>
#include <winsock2.h>
#include <vector>

using namespace std;

struct par 
    SOCKET* s;
    string* buffer;
    bool keep = 1;
;

struct HANDLES 
    HANDLE hRecv;
    HANDLE hSend;
;

unsigned int WINAPI recvThread(LPVOID param) 
    par* data = (par*)param;
    char* inBuf;
    unsigned short int inSize;
    string aux = inBuf;
    string* auxptr = data->buffer;
    SOCKET* s = data->s;
    while(true) 
        inSize = recv(*s, inBuf, 2000, 0);
        inBuf[inSize] = '\0';
        *auxptr = aux; // ???
    


unsigned int WINAPI sendThread(LPVOID param) 
    par* data = (par*)param;
    string auxBuf = "NULL";
    string* auxptr = data->buffer;
    SOCKET* s = data->s;
    while (true) 
        if(auxBuf != (*auxptr)) 
            string auxstring = *auxptr;
            const char* auxchar = auxstring.c_str();
            send(*s, auxchar, strlen(auxchar), 0);
            auxBuf = auxstring;
        
        Sleep(200);
    


int main()

    WSADATA wsa;
    WSAStartup(MAKEWORD(2,2), &wsa);
    string buf = "NULL";
    vector<HANDLES> hVec;

    SOCKET s;
    s = socket(AF_INET, SOCK_STREAM, 0);

    sockaddr_in server;

    server.sin_family = AF_INET;
    server.sin_port = htons(8888);
    server.sin_addr.s_addr = INADDR_ANY;

    bind(s, (sockaddr*)&server, sizeof(server));

    listen(s, 5);

    sockaddr_in clientdir;
    int siz = sizeof(clientdir);
    SOCKET cliente;
    while((cliente = accept(s, (sockaddr*)&clientdir, &siz))) 
        par* newParams;
        newParams->s = &cliente;
        newParams->buffer = &buf;
        if(cliente != INVALID_SOCKET) 
            HANDLES aux;
            aux.hRecv = (HANDLE)_beginthreadex(NULL, 0, recvThread, (void*)newParams, 0, 0);
            aux.hSend = (HANDLE)_beginthreadex(NULL, 0, sendThread, (void*)newParams, 0, 0);
            hVec.push_back(aux);
        
    

它遇到的第一个问题出现在:newParams->s = &cliente; 使服务器崩溃。 如果有人能告诉我我做错了什么以及应该实施的任何其他修复,我将不胜感激。

【问题讨论】:

newParams 未初始化,因此您不能只在下一行使用它newParams-&gt;s... 下次请附上您收到的错误 【参考方案1】:

第一个问题是你有一个未初始化的指针 (newParams),它没有指向任何有效的地方。然后你会使用它,这将导致未定义的行为

当您修复上述问题时(通过使用 new 分配一个新的 par 结构并将 newParams 指向该对象)您有另一个问题:指向 SOCKETstring 结构中的成员。所有的指针,不管你有多少(或几个)连接和线程都指向相同SOCKETstring

如果接收和发送线程应该共享SOCKETstring,那么这些成员不是指针,而是在需要时复制的值,但线程共享结构 em>,通过将相同的newParams 指针传递给两个线程来解决。

还有更多关于未初始化指针的问题,以及数据竞争(因为你没有保护线程共享的资源)。

我的建议是退后一步,并废弃所有您的代码。然后重新编码,同时采取小的婴儿步骤,一次添加一点,同时确保它工作,并且您了解它如何工作。 Rubber-duck debugging 以及使用实际的调试器有很大帮助。和看书。并练习。不要着急,尝试一下子做所有事情。

【讨论】:

谢谢,纠正了指针错误并采纳了您的建议并刮掉了代码。现在它正在工作。

以上是关于C++:无法让套接字、线程和结构工作的主要内容,如果未能解决你的问题,请参考以下文章

Windows 下 C++ 和 C# 中的套接字无法正常工作

调用 fork() 后 SSL_accept 挂起

C++ 套接字 Send() 线程安全

c++ vector<char> 和套接字

具有多个连接的 C++ 服务器套接字

没有多线程的 C++ 套接字非同步/并行代码