aboutsummaryrefslogtreecommitdiffstats
path: root/tcpclient.cpp
blob: 1922b76cb30a583fe8e8f47ec9e3df22af22aba9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/* Copyright (C) 2022 The Qt Company Ltd.
 *
 * SPDX-License-Identifier: GPL-3.0-only WITH Qt-GPL-exception-1.0
*/

#include "tcpclient.h"

TcpClient::TcpClient(const std::string &connAddr, uint16_t port)
{
#ifdef _WIN32
    // Initialize Winsock
    WSADATA wsaData;
    int iResult = 0;
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"Error at WSAStartup()\n");
        exit(EXIT_FAILURE);
    }
    const int inetSuccess = inet_pton(AF_INET, connAddr.c_str(), &m_server.sin_addr.s_addr);
#else
    const int inetSuccess = inet_aton(connAddr.c_str(), &m_server.sin_addr);
#endif
    if (!inetSuccess) {
        // Try to resolve hostname
        struct hostent *host;
        struct in_addr **addrList;
        if ( (host = gethostbyname(connAddr.c_str()) ) == nullptr){
            std::cout << "Failed to resolve hostname\n";
            exit(EXIT_FAILURE);
        }
        addrList = (struct in_addr **) host->h_addr_list;
        m_server.sin_addr = *addrList[0];
    }
    m_server.sin_port = htons(port);
}

int TcpClient::sendAndReceive(const std::string &message, std::string &reply)
{
    m_server.sin_family = AF_INET;
    m_socketFD = (socket(AF_INET , SOCK_STREAM, 0));
    if (m_socketFD < 0) {
        doCloseSocket();
        return e_tcp_fail_socket;
    }

    // Connect to daemon
    int connectR = connect(m_socketFD, (struct sockaddr *)&m_server, sizeof(m_server));
    if (connectR == -1) {
        doCloseSocket();
        return e_tcp_error_conn;
    }
    const size_t bytesSent = send(m_socketFD, message.c_str(), (int)message.length(), 0);

    if (bytesSent < 0 ) { // send failed
        doCloseSocket();
        return e_tcp_error_send;
    }

    std::string resp(BUFFER_SIZE, ' ');
    size_t bytes_recv;
    try {
        bytes_recv = recv(m_socketFD, &resp.front(), (int)resp.size(), 0);
    }
    catch (...) {
        std::cout << "Error receiving" << std::endl;
        doCloseSocket();
        return e_tcp_error_recv;
    }
    if (bytes_recv == -1) {
        doCloseSocket();
        return e_tcp_error_recv;
    }
    doCloseSocket();
    reply = resp.substr(0, bytes_recv); // Had to cut it like this for windows
    return e_tcp_success;
}