feat: add Std::Net — TCP sockets module

- C runtime: socket(), bind(), listen(), accept(), connect(), send(), recv(), close()
- library/std/Net.bux: Net_Create, Net_Bind, Net_Listen, Net_Accept, Net_Connect,
  Net_Send, Net_Recv, Net_Close, Net_SetReuse, Net_LastError
- examples/tcp_server.bux: echo server on 127.0.0.1:9000
- examples/tcp_client.bux: client that sends 'Hello from Bux!' and prints reply
This commit is contained in:
2026-06-05 20:32:10 +03:00
parent 7b3fa2c423
commit ba9f5dfd05
6 changed files with 251 additions and 0 deletions
+87
View File
@@ -9,6 +9,10 @@
#include <pthread.h>
#include <ucontext.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
/* Command-line argument storage */
int g_argc = 0;
@@ -1155,3 +1159,86 @@ char* bux_process_output(const char* cmd) {
pclose(pipe);
return buf;
}
/* ============================================================================
* Network / Socket primitives
* ============================================================================ */
int bux_socket_create(void) {
int fd = socket(AF_INET, SOCK_STREAM, 0);
return fd;
}
int bux_socket_reuse(int fd) {
int opt = 1;
return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
}
int bux_socket_bind(int fd, const char* addr, int port) {
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons((uint16_t)port);
if (addr == NULL || addr[0] == '\0') {
sa.sin_addr.s_addr = INADDR_ANY;
} else {
if (inet_pton(AF_INET, addr, &sa.sin_addr) <= 0) {
return -1;
}
}
return bind(fd, (struct sockaddr*)&sa, sizeof(sa));
}
int bux_socket_listen(int fd, int backlog) {
return listen(fd, backlog);
}
int bux_socket_accept(int fd) {
struct sockaddr_in sa;
socklen_t len = sizeof(sa);
return accept(fd, (struct sockaddr*)&sa, &len);
}
int bux_socket_connect(int fd, const char* addr, int port) {
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons((uint16_t)port);
if (inet_pton(AF_INET, addr, &sa.sin_addr) <= 0) {
return -1;
}
return connect(fd, (struct sockaddr*)&sa, sizeof(sa));
}
int bux_socket_send(int fd, const char* data, int len) {
if (!data || len <= 0) return 0;
return (int)send(fd, data, (size_t)len, 0);
}
BuxString bux_socket_recv(int fd, int max_len) {
BuxString result;
if (max_len <= 0) {
result.data = "";
result.len = 0;
return result;
}
char* buf = (char*)bux_alloc((size_t)max_len + 1);
ssize_t n = recv(fd, buf, (size_t)max_len, 0);
if (n <= 0) {
result.data = "";
result.len = 0;
return result;
}
buf[n] = '\0';
result.data = buf;
result.len = (size_t)n;
return result;
}
int bux_socket_close(int fd) {
return close(fd);
}
const char* bux_socket_error(void) {
return strerror(errno);
}