Search code examples
c++socketsclient-servertcpclient

Using std::thread for send and recive data from TCP socket


I'm developing a TCP socket client. I am trying to write a client that have individual thread for send and receive data. but when I use thread, get a runtime error.

The process goes like this:

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();
}

this code working properly but when I change "main.cpp" to use thread like this:

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

I get "Microsoft Visual C++ Runtime Library" debug error when runing app.

enter image description here

Update: Actually I want to have a function for send and have another function for receive data . but when I use join, my code stay on current function and I can't run another code after that.


Solution

  • you should join the thread after create it

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