1.1.0 release
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
hello_server
|
hello_server
|
||||||
hello_client
|
hello_client
|
||||||
|
hello_server_v6
|
||||||
|
hello_client_v6
|
||||||
chat_server
|
chat_server
|
||||||
chat_client
|
chat_client
|
||||||
udp_server
|
udp_server
|
||||||
|
|||||||
23
Makefile
23
Makefile
@@ -2,13 +2,8 @@ CC=gcc
|
|||||||
CFLAGS=-Wall -Wextra -ggdb -I.
|
CFLAGS=-Wall -Wextra -ggdb -I.
|
||||||
LDFLAGS=-lpthread
|
LDFLAGS=-lpthread
|
||||||
|
|
||||||
all: hello_server hello_client chat_server chat_client udp_server udp_client
|
all: hello_server hello_client hello_server_v6 hello_client_v6 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)
|
|
||||||
|
|
||||||
hello_server: examples/hello_server.c
|
hello_server: examples/hello_server.c
|
||||||
$(CC) $(CFLAGS) -o hello_server examples/hello_server.c $(LDFLAGS)
|
$(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
|
hello_client: examples/hello_client.c
|
||||||
$(CC) $(CFLAGS) -o hello_client examples/hello_client.c $(LDFLAGS)
|
$(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
|
udp_server: examples/udp_server.c
|
||||||
$(CC) $(CFLAGS) -o udp_server examples/udp_server.c $(LDFLAGS)
|
$(CC) $(CFLAGS) -o udp_server examples/udp_server.c $(LDFLAGS)
|
||||||
|
|
||||||
@@ -27,5 +34,7 @@ clean:
|
|||||||
rm -rf chat_client
|
rm -rf chat_client
|
||||||
rm -rf hello_server
|
rm -rf hello_server
|
||||||
rm -rf hello_client
|
rm -rf hello_client
|
||||||
|
rm -rf hello_server_v6
|
||||||
|
rm -rf hello_client_v6
|
||||||
rm -rf udp_server
|
rm -rf udp_server
|
||||||
rm -rf udp_client
|
rm -rf udp_client
|
||||||
|
|||||||
@@ -169,7 +169,8 @@ int main(void)
|
|||||||
}
|
}
|
||||||
pthread_detach(thread);
|
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);
|
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
|
#define SOCK_IMPLEMENTATION
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
|
|
||||||
int main(void) {
|
int main(void)
|
||||||
|
{
|
||||||
char *err = "None";
|
char *err = "None";
|
||||||
|
|
||||||
Sock *sock = sock_create(SOCK_IPV4, SOCK_TCP);
|
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_
|
#ifndef SOCK_H_
|
||||||
#define SOCK_H_
|
#define SOCK_H_
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -76,6 +77,9 @@ ssize_t sock_recvfrom(Sock *sock, void *buf, size_t size, SockAddr *addr);
|
|||||||
// Close a socket
|
// Close a socket
|
||||||
void sock_close(Sock *sock);
|
void sock_close(Sock *sock);
|
||||||
|
|
||||||
|
// Log last errors to stderr
|
||||||
|
void sock_log_errors(void);
|
||||||
|
|
||||||
#endif // SOCK_H_
|
#endif // SOCK_H_
|
||||||
|
|
||||||
#ifdef SOCK_IMPLEMENTATION
|
#ifdef SOCK_IMPLEMENTATION
|
||||||
@@ -111,7 +115,6 @@ Sock *sock_create(SockAddrType domain, SockType type)
|
|||||||
if (sock == NULL) {
|
if (sock == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(sock, 0, sizeof(*sock));
|
memset(sock, 0, sizeof(*sock));
|
||||||
|
|
||||||
sock->type = type;
|
sock->type = type;
|
||||||
@@ -177,12 +180,37 @@ Sock *sock_accept(Sock *sock)
|
|||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(res, 0, sizeof(*res));
|
memset(res, 0, sizeof(*res));
|
||||||
|
|
||||||
res->type = sock->type;
|
res->type = sock->type;
|
||||||
res->fd = fd;
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +220,8 @@ bool sock_connect(Sock *sock, SockAddr addr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sock->addr = addr;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,11 +281,19 @@ void sock_close(Sock *sock)
|
|||||||
free(sock);
|
free(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sock_log_errors(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SOCK ERROR: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SOCK_IMPLEMENTATION
|
#endif // SOCK_IMPLEMENTATION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Revision history:
|
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.3 (2025-04-25) Fix incorrect usage of inet_pton
|
||||||
1.0.2 (2025-04-25) Fix sock_recvfrom not recognizing the address
|
1.0.2 (2025-04-25) Fix sock_recvfrom not recognizing the address
|
||||||
family
|
family
|
||||||
|
|||||||
Reference in New Issue
Block a user