【问题标题】:Socket not open correctly when using Threads c++使用线程c ++时套接字无法正确打开
【发布时间】:2014-07-28 20:13:58
【问题描述】:

嘿,尝试使用套接字和线程。 我试图做一个从一个线程接受客户端并将来自客户端的消息添加到队列中的小程序。并从另一个线程将消息打印到控制台。

但由于某种原因,当我将进程拆分为 2 个线程时,套接字未正确打开,并且监听函数在 WSAGetLastError 上返回 10022 错误。

源代码:

void SlaveThread(queue<char*>* tasks);
void MasterThread(queue<char*>* tasks);

int _tmain(int argc, _TCHAR* argv[])
{
    queue<char*>* tasksQueue = new queue<char*>();

    thread SecondThread(MasterThread,tasksQueue);
    thread FirstThread(SlaveThread,tasksQueue);

    FirstThread.join();
    SecondThread.join();
    return 0;
};


void SlaveThread(queue<char*>* tasks)
{
    while (true)
    {
        if (!tasks->empty())
        {
            cout << tasks->front() << " Queue size : " << tasks->size() << endl;
            tasks->pop();
        }

        Sleep(1000);
    }
};

void MasterThread(queue<char*>* tasks)
{
    WSAData WinSockData;
    WORD Version = MAKEWORD(2, 1);

    WSAStartup(Version, &WinSockData);

    /* Create socket structure */
    SOCKADDR_IN Server;
    Server.sin_addr.s_addr = inet_addr("10.0.0.7");
    Server.sin_family = AF_INET;
    Server.sin_port = htons(27015);

    SOCKET ListenSock = socket(AF_INET, SOCK_STREAM, NULL);
    SOCKET Connect;
    bind(ListenSock, (SOCKADDR*)&Server, sizeof(Server));
    listen(ListenSock, 1);
    int errno1 = WSAGetLastError();
    cout << "Listening on port 27015" << endl;
    //char buffer[200];
    int size = sizeof(Server);
    while (true)
    {
        if (Connect = accept(ListenSock, (SOCKADDR*)&Server, &size)){
            int errno1 = WSAGetLastError();
            cout << "Connection established.. " << endl;
        }
        //if (recv(ListenSock, buffer, 200, 0) > 0)
        //{
        //  tasks->push(buffer);
        //}
    }

    WSACleanup();
};

任何建议为什么当我向程序添加线程时它会中断?因为在空程序上只需使用相同的代码打开套接字就可以正常工作。

【问题讨论】:

  • 你怎么知道ListenSock是有效的?您没有检查来自socket 的返回码。
  • 我现在检查了 ListenSock 的值,它不等于 INVALID_SOCKET 然后我猜它是有效的@SamMiller
  • 10022,FWIW,是无效参数的 WSAEINVAL。
  • @Santa 我知道这个错误是什么意思,但在每个打开套接字的例子中,这是他们发送来监听的值,所以参数应该没问题。 BTW 在 socket() 和 bind() 之后 WSAGetLastError() 返回 0

标签: c++ multithreading sockets winsock


【解决方案1】:

1) 使用 INADDR_ANY 2) 使用 ::bind 而不是绑定。该名称对标准模板库调用不明确。这就是使用命名空间 std 不好的原因。

void MasterThread(queue<char*>* tasks)
{
    WSAData WinSockData;
    WORD Version = MAKEWORD(2, 1);

    WSAStartup(Version, &WinSockData);

    /* Create socket structure */
    SOCKADDR_IN Server;
    Server.sin_addr.s_addr = INADDR_ANY;//inet_addr("10.0.0.7");
    Server.sin_family = AF_INET;
    Server.sin_port = htons(27015);

    SOCKET ListenSock = socket(AF_INET, SOCK_STREAM, NULL);
    SOCKET Connect;
    ::bind(ListenSock, (SOCKADDR*)&Server, sizeof(Server));
    int errno0 = WSAGetLastError();
    listen(ListenSock, 1);
    int errno1 = WSAGetLastError();
    cout << "Listening on port 27015" << endl;
    //char buffer[200];
    int size = sizeof(Server);
    while (true)
    {
        if (Connect = accept(ListenSock, (SOCKADDR*)&Server, &size)){
            int errno1 = WSAGetLastError();
            cout << "Connection established.. " << endl;
        }
        //if (recv(ListenSock, buffer, 200, 0) > 0)
        //{
        //  tasks->push(buffer);
        //}
    }

    WSACleanup();
};

【讨论】:

  • 我认为using namespace std 在这里不会有问题。我怀疑它会将bindstd::bind 混淆。也许重载决议会启动或其他一些魔法..
  • 谢谢! ::bind 解决了,可能你说的有歧义!
  • 不客气。 std::bind 实际编译并运行真是太幸运了!您应该检查所有这些套接字函数的返回值。如果您最初这样做,您会注意到 bind() 没有返回应有的整数。
猜你喜欢
  • 1970-01-01
  • 2020-08-05
  • 2013-09-11
  • 1970-01-01
  • 2013-10-04
  • 1970-01-01
  • 2022-06-13
  • 2017-12-22
  • 2020-01-19
相关资源
最近更新 更多