|
| 1 | +/** |
| 2 | +* @file TCPClient.cpp |
| 3 | +* @brief implementation of the TCP client class |
| 4 | +* @author Mohamed Amine Mzoughi <[email protected]> |
| 5 | +*/ |
| 6 | + |
| 7 | +#include "TCPClient.h" |
| 8 | + |
| 9 | +CTCPClient::CTCPClient(LogFnCallback oLogger) : |
| 10 | + ASocket(oLogger), |
| 11 | + m_eStatus(DISCONNECTED), |
| 12 | + m_ConnectSocket(INVALID_SOCKET), |
| 13 | + m_pResultAddrInfo(nullptr) |
| 14 | + //m_uRetryCount(0), |
| 15 | + //m_uRetryPeriod(0) |
| 16 | +{ |
| 17 | + |
| 18 | +} |
| 19 | + |
| 20 | +// Connexion au serveur |
| 21 | +bool CTCPClient::Connect(const std::string& strServer, const std::string& strPort) |
| 22 | +{ |
| 23 | + if (m_eStatus == CONNECTED) |
| 24 | + { |
| 25 | + Disconnect(); |
| 26 | + m_oLog("[TCPClient][Warning] Opening a new connexion. The last one was automatically closed."); |
| 27 | + } |
| 28 | + |
| 29 | + ZeroMemory(&m_HintsAddrInfo, sizeof(m_HintsAddrInfo)); |
| 30 | + /* AF_INET is used to specify the IPv4 address family. */ |
| 31 | + m_HintsAddrInfo.ai_family = AF_INET; |
| 32 | + /* SOCK_STREAM is used to specify a stream socket. */ |
| 33 | + m_HintsAddrInfo.ai_socktype = SOCK_STREAM; |
| 34 | + /* IPPROTO_TCP is used to specify the TCP protocol. */ |
| 35 | + m_HintsAddrInfo.ai_protocol = IPPROTO_TCP; |
| 36 | + |
| 37 | + /* Resolve the server address and port */ |
| 38 | + int iResult = getaddrinfo(strServer.c_str(), strPort.c_str(), &m_HintsAddrInfo, &m_pResultAddrInfo); |
| 39 | + if (iResult != 0) |
| 40 | + { |
| 41 | + m_oLog(StringFormat("[TCPClient][Error] getaddrinfo failed : %d", iResult)); |
| 42 | + |
| 43 | + if (m_pResultAddrInfo != nullptr) |
| 44 | + { |
| 45 | + freeaddrinfo(m_pResultAddrInfo); |
| 46 | + m_pResultAddrInfo = nullptr; |
| 47 | + } |
| 48 | + |
| 49 | + return false; |
| 50 | + } |
| 51 | + |
| 52 | + // socket creation |
| 53 | + m_ConnectSocket = socket(m_pResultAddrInfo->ai_family, |
| 54 | + m_pResultAddrInfo->ai_socktype, |
| 55 | + m_pResultAddrInfo->ai_protocol); |
| 56 | + |
| 57 | + if (m_ConnectSocket == INVALID_SOCKET) |
| 58 | + { |
| 59 | + m_oLog(StringFormat("[TCPClient][Error] socket failed : %d", WSAGetLastError())); |
| 60 | + freeaddrinfo(m_pResultAddrInfo); |
| 61 | + m_pResultAddrInfo = nullptr; |
| 62 | + return false; |
| 63 | + } |
| 64 | + |
| 65 | + /* |
| 66 | + SOCKET ConnectSocket = INVALID_SOCKET; |
| 67 | + struct sockaddr_in clientService; |
| 68 | +
|
| 69 | + ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
| 70 | + if (ConnectSocket == INVALID_SOCKET) { |
| 71 | + printf("Error at socket(): %ld\n", WSAGetLastError()); |
| 72 | + WSACleanup(); |
| 73 | + return 1; |
| 74 | + } |
| 75 | +
|
| 76 | + // The sockaddr_in structure specifies the address family, |
| 77 | + // IP address, and port of the server to be connected to. |
| 78 | + clientService.sin_family = AF_INET; |
| 79 | + clientService.sin_addr.s_addr = inet_addr("127.0.0.1"); |
| 80 | + clientService.sin_port = htons(27015); |
| 81 | + */ |
| 82 | + |
| 83 | + // connexion to the server |
| 84 | + //unsigned uRetry = 0; |
| 85 | + //do |
| 86 | + //{ |
| 87 | + iResult = connect(m_ConnectSocket, |
| 88 | + m_pResultAddrInfo->ai_addr, |
| 89 | + static_cast<int>(m_pResultAddrInfo->ai_addrlen)); |
| 90 | +//iResult = connect(m_ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)); |
| 91 | + |
| 92 | + //if (iResult != SOCKET_ERROR) |
| 93 | + //break; |
| 94 | + |
| 95 | + // retry mechanism |
| 96 | + //if (uRetry < m_uRetryCount) |
| 97 | + //m_oLog(StringFormat("[TCPClient][Error] connect retry %u after %u second(s)", m_uRetryCount + 1, m_uRetryPeriod)); |
| 98 | + |
| 99 | + //if (m_uRetryPeriod > 0) |
| 100 | + //{ |
| 101 | + //for (unsigned uSec = 0; uSec < m_uRetryPeriod; uSec++) |
| 102 | + //Sleep(1000); |
| 103 | + //} |
| 104 | + //} while (iResult == SOCKET_ERROR && ++uRetry < m_uRetryCount); |
| 105 | + |
| 106 | + freeaddrinfo(m_pResultAddrInfo); |
| 107 | + m_pResultAddrInfo = nullptr; |
| 108 | + |
| 109 | + if (iResult != SOCKET_ERROR) |
| 110 | + { |
| 111 | + m_eStatus = CONNECTED; |
| 112 | + return true; |
| 113 | + } |
| 114 | + m_oLog(StringFormat("[TCPClient][Error] Unable to connect to server : %d", WSAGetLastError())); |
| 115 | + |
| 116 | + return false; |
| 117 | +} |
| 118 | + |
| 119 | +bool CTCPClient::SendData(const char* pData, size_t uSize) const |
| 120 | +{ |
| 121 | + if (m_eStatus != CONNECTED) |
| 122 | + { |
| 123 | + m_oLog("[TCPClient][Error] send failed : not connected to a server."); |
| 124 | + return false; |
| 125 | + } |
| 126 | + |
| 127 | + int iResult = send(m_ConnectSocket, pData, uSize, 0); |
| 128 | + if (iResult == SOCKET_ERROR) |
| 129 | + { |
| 130 | + m_oLog(StringFormat("[TCPClient][Error] send failed : %d", WSAGetLastError())); |
| 131 | + //Disconnect(); |
| 132 | + return false; |
| 133 | + } |
| 134 | + |
| 135 | + return true; |
| 136 | +} |
| 137 | + |
| 138 | +bool CTCPClient::SendData(const std::string& strData) const |
| 139 | +{ |
| 140 | + return SendData(strData.c_str(), strData.length()); |
| 141 | +} |
| 142 | + |
| 143 | +bool CTCPClient::SendData(const std::vector<char>& Data) const |
| 144 | +{ |
| 145 | + return SendData(Data.data(), Data.size()); |
| 146 | +} |
| 147 | + |
| 148 | +bool CTCPClient::Disconnect() |
| 149 | +{ |
| 150 | + if (m_eStatus != CONNECTED) |
| 151 | + return true; |
| 152 | + |
| 153 | + m_eStatus = DISCONNECTED; |
| 154 | + |
| 155 | + // shutdown the connection since no more data will be sent |
| 156 | + int iResult = shutdown(m_ConnectSocket, SD_SEND); |
| 157 | + if (iResult == SOCKET_ERROR) |
| 158 | + { |
| 159 | + m_oLog(StringFormat("[TCPClient][Error] shutdown failed : %d", WSAGetLastError())); |
| 160 | + return false; |
| 161 | + } |
| 162 | + closesocket(m_ConnectSocket); |
| 163 | + |
| 164 | + m_ConnectSocket = INVALID_SOCKET; |
| 165 | + |
| 166 | + if (m_pResultAddrInfo != nullptr) |
| 167 | + { |
| 168 | + freeaddrinfo(m_pResultAddrInfo); |
| 169 | + m_pResultAddrInfo = nullptr; |
| 170 | + } |
| 171 | + |
| 172 | + return true; |
| 173 | +} |
| 174 | + |
| 175 | +CTCPClient::~CTCPClient() |
| 176 | +{ |
| 177 | + if (m_eStatus == CONNECTED) |
| 178 | + Disconnect(); |
| 179 | + |
| 180 | + |
| 181 | +} |
0 commit comments