Implement Server (#1)
All checks were successful
Test and Deploy / test (push) Successful in 15s
Test and Deploy / docs (push) Successful in 28s

- Generic Server struct
- TCP and UDP

Reviewed-on: #1
This commit is contained in:
2024-07-09 21:03:23 +00:00
parent 074798ed62
commit 48f773b3ab
16 changed files with 440 additions and 49 deletions

View File

@ -92,7 +92,8 @@ printf("%s\n", sp[0]); // Prints "Split"
### del_split
Frees all memory used by `split()`. Just like `split`, it does not touch the original string
Frees all memory used by `split()`. Just like `split`, it does not touch the original string.
```c
void del_split(char **sp);
@ -101,3 +102,19 @@ size_t sp_sz = 0;
char **sp = split("Delete Me!", &sp_sz, " ");
void del_split(sp);
```
### capture_system
Runs a command on the system shell and returns stdout as a string. `buffsize` is the size of
the returned buffer that holds `stdout`. Passing `0` to `buffsize` will use the default buffer size of `1024`.
User is responsible for freeing the returned string.
```c
const char *capture_system(const char *cmd, int buffsize);
/* Usage */
const char *cap = capture_system("ls $HOME", 0);
printf("%s\n", cap);
free(cap);
```

106
docs/network.md Normal file
View File

@ -0,0 +1,106 @@
# network
This module provides a generic `Server` type that abstracts away the setup and teardown of a socket
## Enums
### ServerType
Types of servers. Currently supports TCP and UDP, will eventually add UNIX sockets.
```c
typedef enum ServerType {
SERVERTYPE_TCP,
SERVERTYPE_UDP
} ServerType;
```
## Structs
### Server
Server is a generic abstraction over sockets. The type of the server is defined by `server_type`.
```c
typedef struct Server {
ServerType server_type;
int fd;
int port;
void (*handler)(struct Server *s);
} Server;
```
## Functions
### new_server
Create a `Server*`. User is responsible for freeing the memory.
```c
Server *new_server(ServerType type, const char *port, void(handler)(Server *s));
```
### delete_server
Frees the memory allocated for `Server*` and sets the pointer to `NULL`.
```c
void delete_server(Server *s);
```
### serve
Starts up the server. `backlog_size` is the size of the backlog buffer for the underlying socket. Use the macro
`DEFAULT_BACKLOG_SIZE` or pass `0` to use a reasonable default.
```c
int serve(Server *s, int backlog_size);
```
### get_in_addr
Convenience method to get an IP address from a `struct sockaddr_storage` of either IPV4 or IPV6.
```c
void *get_in_addr(struct sockaddr *sa);
/* Usage */
struct sockaddr_storage client_addr;
socklen_t client_addr_sz = sizeof(client_addr);
char buf[33];
if (new_fd = accept(s->fd, (struct sockaddr *)&client_addr, &client_addr_sz) == -1) {
/* error handling */
}
inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), buf, 32);
printf("Received connection from %s\n", buf);
```
### handler_tcp_echo
An example handler for a multithreaded tcp echo server.
```c
void handler_tcp_echo(Server *s);
/* Usage */
#include "lfnetwork.h"
int main(int argc, char **argv) {
Server *server = new_server(SERVERTYPE_TCP, "80", handler_tcp_echo);
serve(server, DEFAULT_BACKLOG);
delete_server(server);
}
```
## Macros
### DEFAULT_BACKLOG_SIZE
A default size for the socket's backlog buffer. `5` is a standard default size, providing some backlog but not
enough to make huge buffers for each socket
```c
#define DEFAULT_BACKLOG_SIZE 5
```