tcp socket client
This commit is contained in:
parent
f37ed538e2
commit
a1932b16c2
10 changed files with 232 additions and 4 deletions
|
@ -29,6 +29,7 @@ add_executable(
|
|||
bus.cpp
|
||||
comm.cpp
|
||||
comm_posix_tty.cpp
|
||||
comm_tcp_socket_client.cpp
|
||||
comm_tcp_socket_server.cpp
|
||||
console.cpp
|
||||
console_ncurses.cpp
|
||||
|
@ -80,6 +81,7 @@ add_executable(
|
|||
bus.cpp
|
||||
comm.cpp
|
||||
comm_posix_tty.cpp
|
||||
comm_tcp_socket_client.cpp
|
||||
comm_tcp_socket_server.cpp
|
||||
console.cpp
|
||||
console_posix.cpp
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../comm_tcp_socket.cpp
|
|
@ -1 +0,0 @@
|
|||
../comm_tcp_socket.h
|
1
ESP32/comm_tcp_socket_client.cpp
Symbolic link
1
ESP32/comm_tcp_socket_client.cpp
Symbolic link
|
@ -0,0 +1 @@
|
|||
../comm_tcp_socket_client.cpp
|
1
ESP32/comm_tcp_socket_client.h
Symbolic link
1
ESP32/comm_tcp_socket_client.h
Symbolic link
|
@ -0,0 +1 @@
|
|||
../comm_tcp_socket_client.h
|
1
ESP32/comm_tcp_socket_server.cpp
Symbolic link
1
ESP32/comm_tcp_socket_server.cpp
Symbolic link
|
@ -0,0 +1 @@
|
|||
../comm_tcp_socket_server.cpp
|
1
ESP32/comm_tcp_socket_server.h
Symbolic link
1
ESP32/comm_tcp_socket_server.h
Symbolic link
|
@ -0,0 +1 @@
|
|||
../comm_tcp_socket_server.h
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
#include "comm.h"
|
||||
#include "comm_esp32_hardwareserial.h"
|
||||
#include "comm_tcp_socket.h"
|
||||
#include "comm_tcp_socket_client.h"
|
||||
#include "comm_tcp_socket_server.h"
|
||||
#if defined(SHA2017)
|
||||
#include "console_shabadge.h"
|
||||
#else
|
||||
|
@ -220,7 +221,7 @@ void start_network(console *const c)
|
|||
|
||||
for(size_t i=comm_interfaces.size(); i<4; i++) {
|
||||
int port = 1100 + i;
|
||||
comm_interfaces.push_back(new comm_tcp_socket(port));
|
||||
comm_interfaces.push_back(new comm_tcp_socket_server(port));
|
||||
DOLOG(info, false, "Configuring DC11 device for TCP socket on port %d", port);
|
||||
}
|
||||
|
||||
|
|
181
comm_tcp_socket_client.cpp
Normal file
181
comm_tcp_socket_client.cpp
Normal file
|
@ -0,0 +1,181 @@
|
|||
// (C) 2024 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#include "gen.h"
|
||||
|
||||
#if defined(ESP32)
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
#include <lwip/netdb.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <driver/uart.h>
|
||||
#elif defined(_WIN32)
|
||||
// from https://stackoverflow.com/questions/12765743/implicit-declaration-of-function-getaddrinfo-on-mingw
|
||||
#define _NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000
|
||||
#define _NTDDI_VERSION_FROM_WIN32_WINNT(ver) _NTDDI_VERSION_FROM_WIN32_WINNT2(ver)
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x501
|
||||
#endif
|
||||
#ifndef NTDDI_VERSION
|
||||
# define NTDDI_VERSION _NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
|
||||
#endif
|
||||
#include <ws2tcpip.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <poll.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#if IS_POSIX
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "comm_tcp_socket_client.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
comm_tcp_socket_client::comm_tcp_socket_client(const std::string & host, const int port) :
|
||||
host(host),
|
||||
port(port)
|
||||
{
|
||||
th = new std::thread(std::ref(*this));
|
||||
}
|
||||
|
||||
comm_tcp_socket_client::~comm_tcp_socket_client()
|
||||
{
|
||||
stop_flag = true;
|
||||
|
||||
if (th) {
|
||||
th->join();
|
||||
delete th;
|
||||
}
|
||||
}
|
||||
|
||||
bool comm_tcp_socket_client::is_connected()
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||
|
||||
return cfd != INVALID_SOCKET;
|
||||
}
|
||||
|
||||
bool comm_tcp_socket_client::has_data()
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||
#if defined(_WIN32)
|
||||
WSAPOLLFD fds[] { { cfd, POLLIN, 0 } };
|
||||
int rc = WSAPoll(fds, 1, 0);
|
||||
#else
|
||||
pollfd fds[] { { cfd, POLLIN, 0 } };
|
||||
int rc = poll(fds, 1, 0);
|
||||
#endif
|
||||
|
||||
return rc == 1;
|
||||
}
|
||||
|
||||
uint8_t comm_tcp_socket_client::get_byte()
|
||||
{
|
||||
int use_fd = -1;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||
use_fd = cfd;
|
||||
}
|
||||
|
||||
uint8_t c = 0;
|
||||
if (read(use_fd, &c, 1) <= 0) {
|
||||
DOLOG(warning, false, "comm_tcp_socket_client::get_byte: failed");
|
||||
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||
close(cfd);
|
||||
cfd = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void comm_tcp_socket_client::send_data(const uint8_t *const in, const size_t n)
|
||||
{
|
||||
const uint8_t *p = in;
|
||||
size_t len = n;
|
||||
|
||||
while(len > 0) {
|
||||
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||
int rc = write(cfd, p, len);
|
||||
if (rc <= 0) { // TODO error checking
|
||||
DOLOG(warning, false, "comm_tcp_socket_client::send_data: failed");
|
||||
close(cfd);
|
||||
cfd = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
|
||||
p += rc;
|
||||
len -= rc;
|
||||
}
|
||||
}
|
||||
|
||||
void comm_tcp_socket_client::operator()()
|
||||
{
|
||||
set_thread_name("kek:COMMTCPC");
|
||||
|
||||
DOLOG(info, true, "TCP comm (client) thread started for %s:%d", host.c_str(), port);
|
||||
|
||||
while(!stop_flag) {
|
||||
myusleep(101000l);
|
||||
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||
if (cfd != INVALID_SOCKET)
|
||||
continue;
|
||||
|
||||
addrinfo *res = nullptr;
|
||||
|
||||
addrinfo hints { };
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
char port_str[8] { 0 };
|
||||
snprintf(port_str, sizeof port_str, "%u", port);
|
||||
|
||||
int rc = getaddrinfo(host.c_str(), port_str, &hints, &res);
|
||||
if (rc != 0) {
|
||||
#ifdef ESP32
|
||||
DOLOG(ll_error, true, "comm_tcp_socket_client: cannot resolve \"%s\":%s", host.c_str(), port_str);
|
||||
#else
|
||||
DOLOG(ll_error, true, "comm_tcp_socket_client: cannot resolve \"%s\":%s: %s", host.c_str(), port_str, gai_strerror(rc));
|
||||
#endif
|
||||
|
||||
myusleep(101000l);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(addrinfo *p = res; p != NULL; p = p->ai_next) {
|
||||
if ((cfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
|
||||
continue;
|
||||
|
||||
if (::connect(cfd, p->ai_addr, p->ai_addrlen) == -1) {
|
||||
close(cfd);
|
||||
cfd = INVALID_SOCKET;
|
||||
DOLOG(ll_error, true, "comm_tcp_socket_client: cannot connect");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (cfd != INVALID_SOCKET)
|
||||
set_nodelay(cfd);
|
||||
}
|
||||
|
||||
DOLOG(info, true, "comm_tcp_socket_client thread terminating");
|
||||
|
||||
close(cfd);
|
||||
}
|
42
comm_tcp_socket_client.h
Normal file
42
comm_tcp_socket_client.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
// (C) 2024 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#include "gen.h"
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include "comm.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <ws2tcpip.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
|
||||
class comm_tcp_socket_client: public comm
|
||||
{
|
||||
private:
|
||||
const std::string host;
|
||||
const int port { -1 };
|
||||
std::atomic_bool stop_flag { false };
|
||||
SOCKET cfd { INVALID_SOCKET };
|
||||
std::mutex cfd_lock;
|
||||
std::thread *th { nullptr };
|
||||
|
||||
public:
|
||||
comm_tcp_socket_client(const std::string & host, const int port);
|
||||
virtual ~comm_tcp_socket_client();
|
||||
|
||||
bool is_connected() override;
|
||||
|
||||
bool has_data() override;
|
||||
uint8_t get_byte() override;
|
||||
|
||||
void send_data(const uint8_t *const in, const size_t n) override;
|
||||
|
||||
void operator()();
|
||||
};
|
Loading…
Add table
Reference in a new issue