1.1.0 release
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,7 @@
|
||||
hello_server
|
||||
hello_client
|
||||
hello_server_v6
|
||||
hello_client_v6
|
||||
chat_server
|
||||
chat_client
|
||||
udp_server
|
||||
|
||||
23
Makefile
23
Makefile
@@ -2,13 +2,8 @@ CC=gcc
|
||||
CFLAGS=-Wall -Wextra -ggdb -I.
|
||||
LDFLAGS=-lpthread
|
||||
|
||||
all: hello_server hello_client chat_server chat_client udp_server udp_client
|
||||
|
||||
chat_server: examples/chat_server.c
|
||||
$(CC) $(CFLAGS) -o chat_server examples/chat_server.c $(LDFLAGS)
|
||||
|
||||
chat_client: examples/chat_client.c
|
||||
$(CC) $(CFLAGS) -o chat_client examples/chat_client.c $(LDFLAGS)
|
||||
all: hello_server hello_client hello_server_v6 hello_client_v6 chat_server \
|
||||
chat_client udp_server udp_client
|
||||
|
||||
hello_server: examples/hello_server.c
|
||||
$(CC) $(CFLAGS) -o hello_server examples/hello_server.c $(LDFLAGS)
|
||||
@@ -16,6 +11,18 @@ hello_server: examples/hello_server.c
|
||||
hello_client: examples/hello_client.c
|
||||
$(CC) $(CFLAGS) -o hello_client examples/hello_client.c $(LDFLAGS)
|
||||
|
||||
hello_server_v6: examples/hello_server_v6.c
|
||||
$(CC) $(CFLAGS) -o hello_server_v6 examples/hello_server_v6.c $(LDFLAGS)
|
||||
|
||||
hello_client_v6: examples/hello_client_v6.c
|
||||
$(CC) $(CFLAGS) -o hello_client_v6 examples/hello_client_v6.c $(LDFLAGS)
|
||||
|
||||
chat_server: examples/chat_server.c
|
||||
$(CC) $(CFLAGS) -o chat_server examples/chat_server.c $(LDFLAGS)
|
||||
|
||||
chat_client: examples/chat_client.c
|
||||
$(CC) $(CFLAGS) -o chat_client examples/chat_client.c $(LDFLAGS)
|
||||
|
||||
udp_server: examples/udp_server.c
|
||||
$(CC) $(CFLAGS) -o udp_server examples/udp_server.c $(LDFLAGS)
|
||||
|
||||
@@ -27,5 +34,7 @@ clean:
|
||||
rm -rf chat_client
|
||||
rm -rf hello_server
|
||||
rm -rf hello_client
|
||||
rm -rf hello_server_v6
|
||||
rm -rf hello_client_v6
|
||||
rm -rf udp_server
|
||||
rm -rf udp_client
|
||||
|
||||
@@ -169,7 +169,8 @@ int main(void)
|
||||
}
|
||||
pthread_detach(thread);
|
||||
|
||||
printf("INFO: New client connected\n");
|
||||
printf("INFO: New client connected from %s:%d\n", client->addr.str,
|
||||
client->addr.port);
|
||||
}
|
||||
|
||||
sock_close(server);
|
||||
|
||||
32
examples/hello_client_v6.c
Normal file
32
examples/hello_client_v6.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define SOCK_IMPLEMENTATION
|
||||
#include "sock.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bool err = false;
|
||||
|
||||
Sock *sock = sock_create(SOCK_IPV6, SOCK_TCP);
|
||||
if (sock == NULL) { err = "create"; goto defer; }
|
||||
|
||||
SockAddr addr = sock_addr("::1", 6969);
|
||||
|
||||
if (!sock_connect(sock, addr)) { err = "connect"; goto defer; }
|
||||
|
||||
const char *msg = "Hello from client!";
|
||||
char buf[128];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
sock_send(sock, msg, strlen(msg));
|
||||
sock_recv(sock, buf, sizeof(buf));
|
||||
printf("%s:%d: %.*s\n", sock->addr.str, sock->addr.port,
|
||||
(int)sizeof(buf), buf);
|
||||
|
||||
defer:
|
||||
sock_close(sock);
|
||||
if (err) sock_log_errors();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
#define SOCK_IMPLEMENTATION
|
||||
#include "sock.h"
|
||||
|
||||
int main(void) {
|
||||
int main(void)
|
||||
{
|
||||
char *err = "None";
|
||||
|
||||
Sock *sock = sock_create(SOCK_IPV4, SOCK_TCP);
|
||||
|
||||
36
examples/hello_server_v6.c
Normal file
36
examples/hello_server_v6.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define SOCK_IMPLEMENTATION
|
||||
#include "sock.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bool err = false;
|
||||
|
||||
Sock *sock = sock_create(SOCK_IPV6, SOCK_TCP);
|
||||
if (sock == NULL) { err = true; goto close; }
|
||||
|
||||
SockAddr addr = sock_addr("::", 6969);
|
||||
if (!sock_bind(sock, addr)) { err = true; goto close; }
|
||||
if (!sock_listen(sock, 16)) { err = true; goto close; }
|
||||
|
||||
Sock *client = sock_accept(sock);
|
||||
if (client == NULL) { err = true; goto close; }
|
||||
|
||||
const char *msg = "Hello from server!";
|
||||
char buf[128];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
sock_send(client, msg, strlen(msg));
|
||||
sock_recv(client, buf, sizeof(buf));
|
||||
printf("%s:%d: %.*s\n", client->addr.str, client->addr.port,
|
||||
(int)sizeof(buf), buf);
|
||||
|
||||
sock_close(client);
|
||||
|
||||
close:
|
||||
sock_close(sock);
|
||||
if (err) sock_log_errors();
|
||||
|
||||
return 0;
|
||||
}
|
||||
44
sock.h
44
sock.h
@@ -1,10 +1,11 @@
|
||||
// sock - v1.0.3 - MIT License - https://github.com/seajee/sock.h
|
||||
// sock - v1.1.0 - MIT License - https://github.com/seajee/sock.h
|
||||
|
||||
#ifndef SOCK_H_
|
||||
#define SOCK_H_
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -76,6 +77,9 @@ ssize_t sock_recvfrom(Sock *sock, void *buf, size_t size, SockAddr *addr);
|
||||
// Close a socket
|
||||
void sock_close(Sock *sock);
|
||||
|
||||
// Log last errors to stderr
|
||||
void sock_log_errors(void);
|
||||
|
||||
#endif // SOCK_H_
|
||||
|
||||
#ifdef SOCK_IMPLEMENTATION
|
||||
@@ -111,7 +115,6 @@ Sock *sock_create(SockAddrType domain, SockType type)
|
||||
if (sock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(sock, 0, sizeof(*sock));
|
||||
|
||||
sock->type = type;
|
||||
@@ -177,12 +180,37 @@ Sock *sock_accept(Sock *sock)
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(res, 0, sizeof(*res));
|
||||
|
||||
res->type = sock->type;
|
||||
res->fd = fd;
|
||||
|
||||
SockAddr *addr = &res->addr;
|
||||
addr->len = sizeof(addr->sockaddr);
|
||||
getpeername(res->fd, &addr->sockaddr, &addr->len);
|
||||
// TODO: This is duplicated code from sock_recvfrom
|
||||
switch (addr->sockaddr.sa_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *ipv4 = &addr->ipv4;
|
||||
addr->type = SOCK_IPV4;
|
||||
addr->port = ntohs(ipv4->sin_port);
|
||||
addr->len = sizeof(*ipv4);
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addr->str, sizeof(addr->str));
|
||||
} break;
|
||||
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *ipv6 = &addr->ipv6;
|
||||
addr->type = SOCK_IPV6;
|
||||
addr->port = ntohs(ipv6->sin6_port);
|
||||
addr->len = sizeof(*ipv6);
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addr->str, sizeof(addr->str));
|
||||
} break;
|
||||
|
||||
default: {
|
||||
assert(false && "Unreachable address family");
|
||||
} break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -192,6 +220,8 @@ bool sock_connect(Sock *sock, SockAddr addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
sock->addr = addr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -251,11 +281,19 @@ void sock_close(Sock *sock)
|
||||
free(sock);
|
||||
}
|
||||
|
||||
void sock_log_errors(void)
|
||||
{
|
||||
fprintf(stderr, "SOCK ERROR: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
#endif // SOCK_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
Revision history:
|
||||
|
||||
1.1.0 (2025-04-26) New sock_log_errors function
|
||||
Fill new Sock's SockAddr after a sock_accept
|
||||
Save remove SockAddr in Sock in sock_connect
|
||||
1.0.3 (2025-04-25) Fix incorrect usage of inet_pton
|
||||
1.0.2 (2025-04-25) Fix sock_recvfrom not recognizing the address
|
||||
family
|
||||
|
||||
Reference in New Issue
Block a user