diff --git a/lab3/demos/Makefile b/lab3/demos/Makefile new file mode 100644 index 0000000..a2f0f6c --- /dev/null +++ b/lab3/demos/Makefile @@ -0,0 +1,10 @@ +all: server client + +server: server.c + gcc -Wall -Wextra -Werror -D_POSIX_C_SOURCE=201112L -o server server.c + +client: client.c + gcc -Wall -Wextra -Werror -D_POSIX_C_SOURCE=201112L -o client client.c + +clean: + rm -f server client diff --git a/lab3/demos/client.c b/lab3/demos/client.c new file mode 100644 index 0000000..5d5c9c9 --- /dev/null +++ b/lab3/demos/client.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include + +#define PORT "1025" +#define HOST "localhost" +#define SOURCE_PORT "1026" + +int create_client_sock(char* port, char* host, char* source_port) { + struct addrinfo hints = { + .ai_family = AF_INET6, + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_V4MAPPED, + }; + + struct addrinfo* res; + int err = getaddrinfo(host, port, &hints, &res); + if (err != 0) { + fprintf(stderr, "%s\n", gai_strerror(err)); + _exit(1); + } + + struct addrinfo *self; + err = getaddrinfo(NULL, source_port, &hints, &self); + if (err != 0) { + fprintf(stderr, "%s\n", gai_strerror(err)); + _exit(1); + } + + int sfd; + struct addrinfo* cur = res; + + for (; cur != NULL; cur = cur->ai_next) { + // socket + sfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (sfd == -1) { + perror("socket"); + continue; + } + + int val = 1; + err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (err == -1) { + perror("setsockopt"); + close(sfd); + continue; + } + + // Bind + err = bind(sfd, self->ai_addr, self->ai_addrlen); + if (err == -1) { + perror("bind"); + close(sfd); + continue; + } + + // Connect + err = connect(sfd, res->ai_addr, res->ai_addrlen); + if (err == -1) { + perror("connect"); + close(sfd); + continue; + } + + break; + } + + freeaddrinfo(res); + freeaddrinfo(self); + + if (cur == NULL) { + fprintf(stderr, "failed to connect to the server\n"); + _exit(1); + } + + return sfd; +} + +int main() { + int cfd = create_client_sock(PORT, HOST, SOURCE_PORT); + + char* msg = "This is a test message!\n"; + write(cfd, msg, strlen(msg)); + printf("message send: \"%s\"\n", msg); + + close(cfd); +} diff --git a/lab3/demos/server.c b/lab3/demos/server.c new file mode 100644 index 0000000..d9cc649 --- /dev/null +++ b/lab3/demos/server.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#define PORT "1025" +#define BACKLOG 4 +#define BUF_SIZE 20 + +int create_server_sock(char* port) { + struct addrinfo hints = { + .ai_family = AF_INET6, + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_PASSIVE || AI_V4MAPPED + }; + + struct addrinfo *res; + int err = getaddrinfo(NULL, port, &hints, &res); + if (err != 0) { + fprintf(stderr, "gai_err %s\n", gai_strerror(err)); + _exit(1); + } + + int sfd; + struct addrinfo* cur = res; + + for (; cur != NULL; cur = cur->ai_next) { + // create socket + sfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (sfd == -1) { + perror("socket"); + continue; + } + + int val = 1; + err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (err == -1) { + perror("setsockopt"); + close(sfd); + continue; + } + + // Bind + err = bind(sfd, cur->ai_addr, cur->ai_addrlen); + if (err == -1) { + perror("bind"); + close(sfd); + continue; + } + + // Listen + err = listen(sfd, BACKLOG); + if (err == -1) { + perror("listen"); + close(sfd); + continue; + } + + break; + } + + freeaddrinfo(res); + + if (cur == NULL) { + fprintf(stderr, "failed to create socket\n"); + close(sfd); + _exit(1); + } + + return sfd; +} + +int main() { + int sfd = create_server_sock(PORT); + + struct sockaddr_storage client_addr; + socklen_t client_addr_len = sizeof(client_addr); + + int cfd = accept(sfd, (struct sockaddr*) &client_addr, &client_addr_len); + if (cfd == -1) { + perror("accept"); + _exit(1); + } + + int n; + uint8_t buf[BUF_SIZE]; + + while ((n = read(cfd, buf, BUF_SIZE)) > 0) { + if (n == -1) { + perror("read"); + _exit(1); + } + if (write(STDOUT_FILENO, buf, n) == -1) { + perror("read"); + _exit(1); + } + } + + close(sfd); + + return 0; +}