mirror of
https://github.com/pumpitupdev/pumptools.git
synced 2026-09-25 07:37:56 +03:00
util/sock-tcp: Add functions for client side data handling
This commit is contained in:
@@ -84,6 +84,80 @@ bool util_sock_tcp_is_connectable3(uint32_t ipv4, uint16_t port, uint32_t timeou
|
||||
return res;
|
||||
}
|
||||
|
||||
int util_sock_tcp_open_bind_listen(const char* ipv4, uint32_t num_connections)
|
||||
{
|
||||
char* address;
|
||||
uint16_t port;
|
||||
|
||||
util_net_split_ipv4_str(ipv4, &address, &port);
|
||||
|
||||
int res = util_sock_tcp_open_bind_listen2(address, port, num_connections);
|
||||
|
||||
free(address);
|
||||
return res;
|
||||
}
|
||||
|
||||
int util_sock_tcp_open_bind_listen2(const char* ipv4, uint16_t port, uint32_t num_connections)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
|
||||
// store this IP address in sa:
|
||||
inet_pton(AF_INET, ipv4, &(sa.sin_addr));
|
||||
|
||||
return util_sock_tcp_open_bind_listen3(htonl(sa.sin_addr.s_addr), port, num_connections);
|
||||
}
|
||||
|
||||
int util_sock_tcp_open_bind_listen3(uint32_t ipv4, uint16_t port, uint32_t num_connections)
|
||||
{
|
||||
int handle;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
handle = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (handle == -1) {
|
||||
log_error("Creating socket (%X, %d) failed: %s", ipv4, port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allow re-using address/port even when considered already bound. The kernel might hold to the port
|
||||
// a little longer, up to a minute, even after a clean shutdown of the application and closing the
|
||||
// socket. This avoids having to wait and quick application restart
|
||||
setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = htonl(ipv4);
|
||||
|
||||
if (bind(handle, (const struct sockaddr*) &addr, sizeof(addr)) == -1) {
|
||||
close(handle);
|
||||
log_error("Binding to %X, %d failed: %s", ipv4, port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(handle, num_connections) == -1) {
|
||||
close(handle);
|
||||
log_error("Listening to %d connections on %X, %d failed: %s", num_connections, ipv4, port, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_debug("Socket opened (%X), bound and listening on %X, port %d", handle, ipv4, port);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int util_sock_tcp_wait_and_accept_remote_connection(int handle)
|
||||
{
|
||||
int con_handle = accept(handle, (struct sockaddr*) NULL, NULL);
|
||||
|
||||
if (con_handle == -1) {
|
||||
log_error("Accepting connection of socket (%X) failed: %s", handle, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return con_handle;
|
||||
}
|
||||
|
||||
int util_sock_tcp_connect(const char* ipv4)
|
||||
{
|
||||
char* address;
|
||||
@@ -135,7 +209,12 @@ int util_sock_tcp_connect3(uint32_t ipv4, uint16_t port)
|
||||
return handle;
|
||||
}
|
||||
|
||||
ssize_t util_sock_tcp_send(int handle, void* buffer, size_t size, uint32_t timeout_ms)
|
||||
ssize_t util_sock_tcp_send_block(int handle, const void* buffer, size_t size)
|
||||
{
|
||||
return send(handle, buffer, size, 0);
|
||||
}
|
||||
|
||||
ssize_t util_sock_tcp_send(int handle, const void* buffer, size_t size, uint32_t timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = (__time_t) (timeout_ms / 1000);
|
||||
@@ -158,6 +237,11 @@ ssize_t util_sock_tcp_send(int handle, void* buffer, size_t size, uint32_t timeo
|
||||
return length;
|
||||
}
|
||||
|
||||
ssize_t util_sock_tcp_recv_block(int handle, void* buffer, size_t size)
|
||||
{
|
||||
return recv(handle, buffer, size, 0);
|
||||
}
|
||||
|
||||
ssize_t util_sock_tcp_recv(int handle, void* buffer, size_t size, uint32_t timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
@@ -17,13 +17,25 @@ bool util_sock_tcp_is_connectable2(const char* ipv4, uint16_t port, uint32_t tim
|
||||
|
||||
bool util_sock_tcp_is_connectable3(uint32_t ipv4, uint16_t port, uint32_t timeout_ms);
|
||||
|
||||
int util_sock_tcp_open_bind_listen(const char* ipv4, uint32_t num_connections);
|
||||
|
||||
int util_sock_tcp_open_bind_listen2(const char* ipv4, uint16_t port, uint32_t num_connections);
|
||||
|
||||
int util_sock_tcp_open_bind_listen3(uint32_t ipv4, uint16_t port, uint32_t num_connections);
|
||||
|
||||
int util_sock_tcp_wait_and_accept_remote_connection(int handle);
|
||||
|
||||
int util_sock_tcp_connect(const char* ipv4);
|
||||
|
||||
int util_sock_tcp_connect2(const char* ipv4, uint16_t port);
|
||||
|
||||
int util_sock_tcp_connect3(uint32_t ipv4, uint16_t port);
|
||||
|
||||
ssize_t util_sock_tcp_send(int handle, void* buffer, size_t size, uint32_t timeout_ms);
|
||||
ssize_t util_sock_tcp_send_block(int handle, const void* buffer, size_t size);
|
||||
|
||||
ssize_t util_sock_tcp_send(int handle, const void* buffer, size_t size, uint32_t timeout_ms);
|
||||
|
||||
ssize_t util_sock_tcp_recv_block(int handle, void* buffer, size_t size);
|
||||
|
||||
ssize_t util_sock_tcp_recv(int handle, void* buffer, size_t size, uint32_t timeout_ms);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user