【问题标题】:Using std::thread for send and recive data from TCP socket使用 std::thread 从 TCP 套接字发送和接收数据
【发布时间】:2021-10-23 10:37:10
【问题描述】:

我正在开发一个 TCP 套接字客户端。我正在尝试编写一个具有用于发送和接收数据的单独线程的客户端。但是当我使用线程时,会出现运行时错误。

流程如下:

main.cpp:

#include <iostream>
#include <thread>
#include <string>
#include <chrono>
#include <WS2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

#include "TCPConnection.h"

SOCKET sock;

void SendRecive(SOCKET *isock) {
    // Do-While loop to send and recive data
    char buf[4096];

    while (true) {
        // Prompt the user for some text
        cout << "> ";
        // Wait for response
        ZeroMemory(buf, 4096);
        auto byteRecived = recv(*isock, buf, 4096, 0);
        if (byteRecived <= 0) continue;
        // Echo response to console
        cout << "SERVER> " << string(buf, 0, byteRecived) << endl;
    }
}

using namespace std;

int main() {
    TCPConnection tcpconn("192.168.1.4", 7705, &sock);
    SendRecive(&sock);
    return 0;
}

TCPConnection.h:

//
// Created by Hamed on 8/21/2021.
//

#ifndef TCPCLIENT_TCPCONNECTION_H
#define TCPCLIENT_TCPCONNECTION_H

#include <iostream>
#include <thread>
#include <string>
#include <WS2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

using namespace std;

class TCPConnection {
public:
    SOCKET *isock;
    TCPConnection(string ServerIPAddress, int ServerPort, SOCKET *sock);
    ~TCPConnection();
};

#endif //TCPCLIENT_TCPCONNECTION_H

TCPConnection.cpp:

#include "TCPConnection.h"

TCPConnection::TCPConnection(string ServerIPAddress, int ServerPort, SOCKET *sock) {
    // Initialize WinSock
    WSAData data{};
    WORD ver = MAKEWORD(2, 2);
    int wsResult = WSAStartup(ver, &data);
    if (wsResult != 0) {
        cerr << "Can't start winsock, Err #" << wsResult << endl;
        return;
    }

    // Create socket
    *sock = socket(AF_INET, SOCK_STREAM, 0);
    if (*sock == INVALID_SOCKET) {
        cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
        WSACleanup();
        return;
    }

    // Fill in a hint structure
    sockaddr_in hint{};
    hint.sin_family = AF_INET;
    hint.sin_port = htons(ServerPort);
    inet_pton(AF_INET, ServerIPAddress.c_str(), &hint.sin_addr);

    // connect to server
    int connResult = connect(*sock, (sockaddr *) &hint, sizeof(hint));
    if (connResult == SOCKET_ERROR) {
        cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
        closesocket(*sock);
        WSACleanup();
        return;
    }
    isock = sock;
}



TCPConnection::~TCPConnection() {
    // Gracefully close down everything
    closesocket(*isock);
    WSACleanup();
}

这段代码可以正常工作,但是当我将“main.cpp”更改为使用这样的线程时:

int main() {
    TCPConnection tcpconn("192.168.1.4", 7705, &sock);    
    thread DoRunTCPRecive(SendRecive,&sock);
    return 0;
}

运行应用程序时出现“Microsoft Visual C++ 运行时库”调试错误。

更新: 其实我想有一个发送功能和另一个接收数据的功能。但是当我使用 join 时,我的代码停留在当前函数上,之后我无法运行其他代码。

【问题讨论】:

    标签: c++ sockets client-server tcpclient


    【解决方案1】:

    你应该在创建线程后加入线程

        thread DoRunTCPRecive(SendRecive,&sock);
        DoRunTCPRecive.join()
    

    【讨论】:

    • 我想在这个函数旁边运行另一个函数。实际上我想有一个发送功能并有另一个接收数据的功能。但是当我使用 join 时,我的代码停留在这一行。
    • 你的意思是你想在主线程中发送数据?对吧?
    • 不,我想要两个线程。其中一个发送数据,第二个线程接收数据。
    • 那么你可以像这个线程一样做 DoRunTCPRecive(SendRecive,&sock);线程 DoRunTCPSend(...); DoRunTCPRecive.join();DoRunTCPSend.join();
    • @user3123721 每当你有一个线程时,你要么等待它完成(通过加入),要么不等待它完成(通过分离)
    猜你喜欢
    • 2016-05-09
    • 2013-07-04
    • 2019-05-07
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多