1+ #include " TCPClient.h"
2+
3+ #include < sys/socket.h>
4+ #include < stdexcept>
5+
6+ #include < arpa/inet.h>
7+ #include < netinet/in.h>
8+ #include < unistd.h>
9+
10+ TCPClient::TCPClient (const std::string& host, uint16_t port)
11+ : host_{host}, port_{port}, client_fd_{-1 } {}
12+
13+ bool TCPClient::connect () {
14+ client_fd_ = socket (AF_INET, SOCK_STREAM, 0 );
15+ if (client_fd_ < 0 ) {
16+ throw std::runtime_error (" socket failed." );
17+ }
18+
19+ // specifying the address
20+ sockaddr_in serverAddress{};
21+ serverAddress.sin_family = AF_INET;
22+ serverAddress.sin_port = htons (port_);
23+
24+ // serverAddress.sin_addr.s_addr = INADDR_ANY;
25+ if (::inet_pton (AF_INET, host_.c_str (), &serverAddress.sin_addr ) <= 0 ) {
26+ throw std::runtime_error (" invalid address" );
27+ }
28+
29+ // sending connection request
30+ return (
31+ ::connect (client_fd_,
32+ reinterpret_cast <sockaddr*>(&serverAddress), // global syscall
33+ sizeof(serverAddress)) == 0);
34+ }
35+
36+ void TCPClient::send (const std::string& msg) {
37+ if (client_fd_ < 0 ) {
38+ throw std::runtime_error (" socket not connected" );
39+ }
40+
41+ const char * data = msg.c_str ();
42+ size_t total = 0 ;
43+ size_t len = msg.size ();
44+ while (total < len) {
45+ ssize_t sent = ::send (client_fd_, data + total, len - total, 0 );
46+ if (sent <= 0 ) {
47+ throw std::runtime_error (" send failed" );
48+ }
49+ total += sent;
50+ }
51+ }
52+
53+ std::string TCPClient::receive () {
54+ if (client_fd_ < 0 ) {
55+ throw std::runtime_error (" socket not connected" );
56+ }
57+
58+ char buffer[1024 ];
59+
60+ ssize_t bytes = recv (client_fd_, buffer, sizeof (buffer), 0 );
61+ if (bytes < 0 ) {
62+ throw std::runtime_error (" recv failed" );
63+ }
64+
65+ if (bytes == 0 ) {
66+ throw std::runtime_error (" connection closed" );
67+ }
68+
69+ return std::string (buffer, bytes);
70+ }
71+
72+ void TCPClient::close () {
73+ if (client_fd_ >= 0 ) {
74+ ::close (client_fd_);
75+ client_fd_ = -1 ;
76+ }
77+ }
0 commit comments