Win32 socket vs POSIX sockets is not always happy together. Seperated the two to mimic the same behavior we have for /uart/. The code compiles but the socket doesnt work on Proxspace yet. More fixes to be done

This commit is contained in:
iceman1001 2025-07-09 00:20:43 +02:00
commit 931e93a11b
3 changed files with 121 additions and 44 deletions

View file

@ -1,23 +1,21 @@
#if !defined(__POSIX_SOCKET_TEMPLATE_H__) #if !defined(__POSIX_SOCKET_TEMPLATE_H__)
#define __POSIX_SOCKET_TEMPLATE_H__ #define __POSIX_SOCKET_TEMPLATE_H__
#include <stdio.h> #ifndef _WIN32
#include <sys/types.h>
#if !defined(WIN32)
#include <sys/socket.h>
#include <netdb.h>
#else
#include <ws2tcpip.h>
#endif
#if defined(__VMS)
#include <ioctl.h>
#endif
#include <fcntl.h>
#include <unistd.h>
/* #include <stdio.h>
A template for opening a non-blocking POSIX socket. #include <unistd.h>
*/ #include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
// A template for opening a non-blocking POSIX socket.
void close_nb_socket(int sockfd);
int open_nb_socket(const char *addr, const char *port); int open_nb_socket(const char *addr, const char *port);
int open_nb_socket(const char *addr, const char *port) { int open_nb_socket(const char *addr, const char *port) {
@ -27,21 +25,23 @@ int open_nb_socket(const char *addr, const char *port) {
hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */ hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Must be TCP */ hints.ai_socktype = SOCK_STREAM; /* Must be TCP */
int sockfd = -1;
int rv;
struct addrinfo *p, *servinfo; struct addrinfo *p, *servinfo;
/* get address information */ /* get address information */
rv = getaddrinfo(addr, port, &hints, &servinfo); int rv = getaddrinfo(addr, port, &hints, &servinfo);
if (rv != 0) { if (rv != 0) {
fprintf(stderr, "Failed to open socket (getaddrinfo): %s\n", gai_strerror(rv)); fprintf(stderr, "Failed to open socket (getaddrinfo): %s\n", gai_strerror(rv));
return -1; return -1;
} }
/* open the first possible socket */ /* open the first possible socket */
int sockfd = -1;
for (p = servinfo; p != NULL; p = p->ai_next) { for (p = servinfo; p != NULL; p = p->ai_next) {
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sockfd == -1) continue; if (sockfd == -1) {
continue;
}
/* connect to server */ /* connect to server */
rv = connect(sockfd, p->ai_addr, p->ai_addrlen); rv = connect(sockfd, p->ai_addr, p->ai_addrlen);
@ -53,42 +53,21 @@ int open_nb_socket(const char *addr, const char *port) {
break; break;
} }
/* free servinfo */ // free servinfo
freeaddrinfo(servinfo); freeaddrinfo(servinfo);
/* make non-blocking */ // make non-blocking
#if !defined(WIN32)
if (sockfd != -1) { if (sockfd != -1) {
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK); fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
} }
#else
if (sockfd != INVALID_SOCKET) {
int iMode = 1;
ioctlsocket(sockfd, FIONBIO, &iMode);
}
#endif
#if defined(__VMS)
/*
OpenVMS only partially implements fcntl. It works on file descriptors
but silently fails on socket descriptors. So we need to fall back on
to the older ioctl system to set non-blocking IO
*/
int on = 1;
if (sockfd != -1) {
ioctl(sockfd, FIONBIO, &on);
}
#endif
/* return the new socket fd */
return sockfd; return sockfd;
} }
void close_nb_socket(int sockfd);
void close_nb_socket(int sockfd) { void close_nb_socket(int sockfd) {
if (sockfd != -1) { if (sockfd != -1) {
close(sockfd); close(sockfd);
} }
} }
#endif #endif
#endif

View file

@ -0,0 +1,91 @@
#if !defined(__WIN32_SOCKET_TEMPLATE_H__)
#include <stdio.h>
#include <unistd.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
void close_nb_socket(int sockfd);
int open_nb_socket(const char *addr, const char *port);
int open_nb_socket(const char *addr, const char *port) {
WSADATA wsaData;
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (res != 0) {
fprintf(stderr, "error: WSAStartup failed with error: %i", res);
return -1;
}
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // Must be TCP
hints.ai_protocol = IPPROTO_TCP; //
struct addrinfo *p, *servinfo;
// get address information
int rv = getaddrinfo(addr, port, &hints, &servinfo);
if (rv != 0) {
fprintf(stderr, "error: getaddrinfo: %s", gai_strerror(rv));
WSACleanup();
return -1;
}
/* open the first possible socket */
SOCKET hSocket = INVALID_SOCKET;
for (p = servinfo; p != NULL; p = p->ai_next) {
hSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (hSocket == INVALID_SOCKET) {
continue;
}
// connect to server
if (connect(hSocket, p->ai_addr, (int)p->ai_addrlen) != INVALID_SOCKET) {
break;
}
closesocket(hSocket);
hSocket = INVALID_SOCKET;
}
// free servinfo
freeaddrinfo(servinfo);
if (p == NULL) { // No address succeeded
fprintf(stderr, "error: Could not connect");
WSACleanup();
return -1;
}
// make non-blocking
if (hSocket != INVALID_SOCKET) {
uint32_t mode; // FIONBIO returns size on 32b
ioctlsocket(hSocket, FIONBIO, (u_long *)&mode);
}
int flag = 1;
res = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
if (res != 0) {
closesocket(hSocket);
WSACleanup();
return -1;
}
return hSocket;
}
void close_nb_socket(int sockfd) {
if (sockfd != -1) {
close(sockfd);
}
}
#endif
#endif

View file

@ -21,7 +21,12 @@
#include "cliparser.h" #include "cliparser.h"
#include "mqtt.h" // MQTT support #include "mqtt.h" // MQTT support
//#include "mbedtls_sockets.h" // MQTT networkings examples //#include "mbedtls_sockets.h" // MQTT networkings examples
#ifndef _WIN32
#include "posix_sockets.h" // MQTT networkings examples #include "posix_sockets.h" // MQTT networkings examples
#else
#include "win32_sockets.h" // MQTT networkings examples
#endif
#include "util_posix.h" // time #include "util_posix.h" // time
#include "fileutils.h" #include "fileutils.h"
@ -62,7 +67,9 @@ static int mqtt_exit(int status, int sockfd, pthread_t *client_daemon) {
if (client_daemon != NULL) { if (client_daemon != NULL) {
pthread_cancel(*client_daemon); pthread_cancel(*client_daemon);
#ifndef _WIN32
pthread_join(*client_daemon, NULL); // Wait for the thread to finish pthread_join(*client_daemon, NULL); // Wait for the thread to finish
#endif
} }
return status; return status;
} }