diff options
author | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-10-21 00:12:02 +0200 |
---|---|---|
committer | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-10-21 00:12:02 +0200 |
commit | d4e7c6876eed2733a2678668bdcabdd87659e826 (patch) | |
tree | 5943038b081f7392182542fc62b2ba2a9f8619bc | |
parent | f6eef73f7f0e805811bb9c2d748c17d558615a74 (diff) |
Added common code for messages
- add: send_message, receive_message functions
- change: use u8, u16, u32, where possible
- fix: use PORT in server.c
-rw-r--r-- | client.c | 20 | ||||
-rw-r--r-- | common.c | 61 | ||||
-rw-r--r-- | common.h | 8 | ||||
-rw-r--r-- | server.c | 34 |
4 files changed, 92 insertions, 31 deletions
@@ -79,10 +79,10 @@ void screen_welcome() void add_message(struct message msg) { int i; - for (i = 0; (messages[nmessages].text[i] = msg.text[i]); i++) + messages[nmessages].text = input.text; ; - messages[nmessages].text[i] = 0; - messages[nmessages].len = i; + messages[nmessages].text[input.len] = 0; + messages[nmessages].len = input.len; for (i = 0; (messages[nmessages].timestamp[i] = msg.timestamp[i]); i++) ; messages[nmessages].timestamp[i] = 0; @@ -109,6 +109,8 @@ int main(void) time_t now; // localtime of new sent message struct tm *ltime; + char buf[MESSAGE_MAX]; + input.text = buf; int serverfd, ttyfd, resizefd; struct message msg_recv = {0}; @@ -233,17 +235,9 @@ int main(void) } else if (fds[FD_SERVER].revents & POLLIN) { int nrecv = recv(serverfd, &msg_recv, sizeof(struct message), 0); - // // TODO: check if bytes are correct - // cleanup(); - // FILE *f = fopen("client_recv.bin", "wb"); - // fwrite(&msg_recv, sizeof(struct message), 1, f); - // fclose(f); - // - // printf("written %lu bytes to client_recv.bin\n", sizeof(msg_recv)); - // return 0; - - // Server closes if (nrecv == 0) { + // Server closed + // TODO: error message like (disconnected) break; } else if (nrecv == -1) { err_exit("Error while receiveiving from server."); @@ -3,8 +3,10 @@ #include <stdarg.h> #include <stdint.h> #include <stdio.h> -#include <strings.h> +#include <string.h> #include <unistd.h> +#include <sys/socket.h> + void writef(char *format, ...) { @@ -74,3 +76,60 @@ u8 load_message(struct message *msg, FILE *f) return 0; } + +u32 send_message(struct message msg, u32 serverfd) +{ + // stream length : message author : message timestamp : message text + u32 buf_len = sizeof(buf_len) + MESSAGE_AUTHOR_LEN + MESSAGE_TIMESTAMP_LEN + msg.len; + char buf[buf_len]; + u32 offset; + + memcpy(buf, &buf_len, sizeof(buf_len)); + offset = sizeof(buf_len); + memcpy(buf + offset, msg.author, MESSAGE_AUTHOR_LEN); + offset += MESSAGE_AUTHOR_LEN; + memcpy(buf + offset, msg.timestamp, MESSAGE_TIMESTAMP_LEN); + offset += MESSAGE_TIMESTAMP_LEN; + memcpy(buf + offset, msg.text, msg.len); + + u32 n = send(serverfd, &buf, buf_len, 0); + if (n == -1) + return n; + + writef("%d bytes sent.\n", n); + return n; +} + +u32 receive_message(struct message *msg, u32 clientfd) +{ + // must all be of the s + u32 nrecv, buf_len; + // limit on what can be received with recv() + u32 buf_size = 20; + // temporary buffer to receive message data over a stream + char recv_buf[BUF_MAX]; + + nrecv = recv(clientfd, recv_buf, buf_size, 0); + if (nrecv == 0 || nrecv == -1) + return nrecv; + + memcpy(&buf_len, recv_buf, sizeof(buf_len)); + + u32 i = 0; + while (nrecv < buf_len) { + // advance the copying by the amounts of bytes received each time + i = recv(clientfd, recv_buf + nrecv, buf_size, 0); + if (i == 0 || i == -1) + return nrecv; + nrecv += i; + } + + struct message received = {0}; + memcpy(&received, recv_buf + sizeof(buf_len), MESSAGE_AUTHOR_LEN + MESSAGE_TIMESTAMP_LEN); + received.text = recv_buf + sizeof(buf_len) + MESSAGE_AUTHOR_LEN + MESSAGE_TIMESTAMP_LEN; + received.len = buf_len - sizeof(buf_len) - MESSAGE_AUTHOR_LEN - MESSAGE_TIMESTAMP_LEN; + + // assume clientfd is serverfd + 1; + writef("Received %d bytes from client(%d): %s [%s] %s\n", nrecv, clientfd - 3, received.timestamp, received.author, received.text); + return nrecv; +} @@ -39,3 +39,11 @@ u8 save_message(struct message *msg, FILE *f); // load the message msg from file f, returns zero on success, returns 1 if the msg.text // was empty which should not be allowed. u8 load_message(struct message *msg, FILE *f); + +// Send a stream of bytes containing msg +// return -1 if send() returns -1. Otherwise returns number of bytes sent. +u32 send_message(struct message msg, u32 serverfd); +// Receives a stream of bytes and populates msg with the data received +// if recv() returns 0 or -1 it will return early and return 0 or -1 accordingly. +// Otherwise returns the number of bytes received +u32 receive_message(struct message *msg, u32 clientfd); @@ -5,6 +5,7 @@ #include <poll.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/socket.h> #include <unistd.h> @@ -14,7 +15,7 @@ static const char *filename = "history.dat"; enum { FD_SERVER = 0 }; -int serverfd; +u32 serverfd; void err_exit(const char *msg) { @@ -27,9 +28,9 @@ void err_exit(const char *msg) int main(void) { - int clientfd; - int nclient = 0; - int on = 1; + u32 clientfd; + u16 nclient = 0; + u8 on = 1; struct message msg_recv = {0}; serverfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); @@ -38,7 +39,7 @@ int main(void) const struct sockaddr_in address = { AF_INET, - htons(9999), + htons(PORT), {0}, }; @@ -60,7 +61,7 @@ int main(void) }; for (;;) { - int ret = poll(fds, FD_MAX, 50000); + u32 ret = poll(fds, FD_MAX, 50000); if (ret == -1) err_exit("Error while polling"); else if (ret == 0) { @@ -85,7 +86,7 @@ int main(void) nclient++; // get a new available spot in the fds array - int i; + u32 i; for (i = 0; i < MAX_CONNECTIONS; i++) if (fds[i].fd == -1) break; @@ -98,15 +99,15 @@ int main(void) } // Check for events on connected clients - for (int i = 1; i <= nclient; i++) { + for (u32 i = 1; i <= nclient; i++) { if (!(fds[i].revents & POLLIN)) continue; - int nrecv; + u32 nrecv; clientfd = fds[i].fd; - nrecv = recv(clientfd, &msg_recv, sizeof(struct message), 0); + nrecv = receive_message(&msg_recv, clientfd); if (nrecv == 0) { printf("client %d disconnected.\n", i); fds[i].fd = -1; @@ -122,10 +123,8 @@ int main(void) err_exit("Error while receiving from client socket."); } - printf("client %d sent %d bytes.\n", i, nrecv); - // TODO: - for (int j = 1; j <= nclient; j++) { + for (u32 j = 1; j <= nclient; j++) { // skip the client that sent the message if (j == i) continue; @@ -136,10 +135,11 @@ int main(void) } // // TODO: Serialize received message - FILE *f = fopen(filename, "wb"); - save_message(&msg_recv, f); - fclose(f); - // return 0; + // FILE *f = fopen(filename, "wb"); + // save_message(&msg_recv, f); + // fclose(f); + // // return 0; + } } |