47 #include <arpa/inet.h> 48 #include <sys/socket.h> 59 static void _printWinError(
const char *
function, DWORD hResult) {
61 LPSTR errorText = NULL;
62 const DWORD r = FormatMessageA(
63 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
66 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
85 const int r = WSAStartup(WINSOCK_VERSION, &wsaData);
90 case WSAVERNOTSUPPORTED:
95 _printWinError(
"WSAStartup", r);
107 const int r = WSACleanup();
111 case WSANOTINITIALISED:
115 _printWinError(
"WSACleanup", r);
153 iret = closesocket(sckt->
socket);
155 iret = close(sckt->
socket);
188 char *buffer_temp = (
char*)buffer;
191 const c_ssize_t nbytes = recv(sckt->
socket, buffer_temp, stillToRead, 0);
196 else if (nbytes == 0) {
199 logMsg(
c_logger_Severity_INFO,
"%s(): client disconnected (requested=%"PRIdMAX
", remaining=%"PRIdMAX
").", __func__, (intmax_t)totalToRead, (intmax_t)stillToRead);
200 return totalToRead - stillToRead;
202 stillToRead -= nbytes;
203 buffer_temp += nbytes;
204 }
while (stillToRead > 0);
206 if (stillToRead != 0) {
210 return totalToRead - stillToRead;
251 const char* buffer_temp = (
const char*)buffer;
254 const c_ssize_t nbytes = send(sckt->
socket, buffer_temp, stillToSend, 0);
259 stillToSend -= nbytes;
260 buffer_temp += nbytes;
261 }
while (stillToSend > 0);
263 if (stillToSend != 0) {
267 return totalToSend - stillToSend;
281 return c_send(sckt, buffer, totSize);
290 sckt->
socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
295 return bind(sckt->
socket, addr, addrlen);
299 return listen(sckt->
socket, backlog);
304 if (client == NULL) {
313 return connect(sckt->
socket, addr, addrlen);
320 struct sockaddr_in hints = { 0 };
322 struct sockaddr_in addr_server = { 0 };
324 uint16_t port = *_port;
337 iret = setsockopt(server_local->
socket, SOL_SOCKET, SO_REUSEADDR, (
char*)&on,
sizeof(on));
344 hints.sin_family = AF_INET;
345 hints.sin_addr.s_addr =
c_hton32(inaddr);
347 iret =
c_bind(server_local, (
struct sockaddr*)&hints,
sizeof(hints));
355 iret =
c_listen(server_local, SOMAXCONN);
362 iret = getsockname(server_local->
socket, (
struct sockaddr*)&addr_server, &addr_server_len);
374 char buf[INET_ADDRSTRLEN];
375 if (inet_ntop(AF_INET, &addr_server.sin_addr, buf,
sizeof(buf)) != NULL)
380 *_port =
c_ntoh16(addr_server.sin_port);
390 *server = server_local;
396 if (server == NULL || client == NULL)
399 struct sockaddr_in addr_client = { 0 };
405 c_socket_t *client_local =
c_accept(server, (
struct sockaddr*)&addr_client, &addr_client_len);
408 if (client_local != NULL)
413 *client = client_local;
416 char buf[INET_ADDRSTRLEN];
417 if (inet_ntop(AF_INET, &addr_client.sin_addr, buf,
sizeof(buf)) != NULL)
441 iret = setsockopt(client_local->
socket, SOL_SOCKET, SO_REUSEADDR, (
char*)&on,
sizeof(on));
448 iret =
c_connect(client_local, addr_server, addrlen);
463 *client = client_local;
468 struct sockaddr_in addr_server = { 0 };
477 struct hostent *he = gethostbyname(hostname);
486 c_memcpy(&addr_server.sin_addr.s_addr, he->h_addr, he->h_length);
487 addr_server.sin_family = AF_INET;
488 addr_server.sin_port =
c_hton16(port);
int32_t c_mutex_lock(c_mutex_t *m)
c_mutex_t mutex
A mutex, use by some functions.
static void * c_memcpy(void *__restrict dest, const void *__restrict src, size_t size)
Wrapper to memcpy(dest, src, size), with check for NULL arguments.
int32_t c_mutex_init(c_mutex_t *m)
int32_t c_socket_client_sockaddr_connect(c_socket_t **client, const struct sockaddr *addr_server, c_socklen_t addrlen)
int c_listen(const c_socket_t *sckt, int backlog)
int32_t c_mutex_destroy(c_mutex_t *m)
int32_t c_socket_cleanup(void)
void c_socket_delete(c_socket_t *sckt)
c_socket_t * c_accept(const c_socket_t *sckt, struct sockaddr *addr, c_socklen_t *addrlen)
#define c_socket_max_ssize
Maximum value accepted as size by send() and recv(). Type is size_t.
c_socket_t * c_tcp_socket(void)
c_socket_type_t socket
The socket.
c_ssize_t c_send_lock(c_socket_t *sckt, const void *buffer, size_t totSize)
#define c_socket_error
Functions like send() and recv() return -1 in case of error. Type is c_ssize_t.
c_ssize_t c_recv_unlock(c_socket_t *sckt, void *buffer, size_t totSize)
int32_t c_socket_client_connect(c_socket_t **client, const char *hostname, uint16_t port)
#define c_socket_invalid
Functions like accept() return -1 in case of error. Type is c_socket_type_t.
static uint16_t c_hton16(uint16_t x)
Functions to handle threads, inspired to C11 threads.h.
void * c_malloc(size_t size)
Generic wrappers to platform-dependent functions.
#define INIT_C_LOGGER(fname, mname)
#define c_socket_h_errno
Network database operations like gethostbyname() set the error into h_errno variable. Type is int.
static uint32_t c_hton32(uint32_t x)
ssize_t c_ssize_t
Return type of send() and recv().
int c_connect(const c_socket_t *sckt, const struct sockaddr *addr, c_socklen_t addrlen)
c_socket_t * c_socket_new(void)
int32_t c_socket_server_init(c_socket_t **server, uint32_t inaddr, uint16_t *_port)
socklen_t c_socklen_t
See definition on Windows case.
int32_t c_socket_server_accept(const c_socket_t *server, c_socket_t **client)
int c_bind(const c_socket_t *sckt, const struct sockaddr *addr, c_socklen_t addrlen)
#define c_use_decl_annotations
c_ssize_t c_send(const c_socket_t *sckt, const void *buffer, size_t totSize)
c_ssize_t c_recv(const c_socket_t *sckt, void *buffer, size_t totSize)
int32_t c_socket_init(void)
void c_socket_reset(c_socket_t *sckt)
static uint16_t c_ntoh16(uint16_t x)
int32_t c_mutex_unlock(c_mutex_t *m)
#define c_socket_errno
Socket-related functions set the error into errno variable. Type is int.