aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymaekers Luca <raymaekers.luca@gmail.com>2024-10-21 00:12:02 +0200
committerRaymaekers Luca <raymaekers.luca@gmail.com>2024-10-21 00:12:02 +0200
commitd4e7c6876eed2733a2678668bdcabdd87659e826 (patch)
tree5943038b081f7392182542fc62b2ba2a9f8619bc
parentf6eef73f7f0e805811bb9c2d748c17d558615a74 (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.c20
-rw-r--r--common.c61
-rw-r--r--common.h8
-rw-r--r--server.c34
4 files changed, 92 insertions, 31 deletions
diff --git a/client.c b/client.c
index cf60853..a1800c1 100644
--- a/client.c
+++ b/client.c
@@ -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.");
diff --git a/common.c b/common.c
index 232cf64..34bed33 100644
--- a/common.c
+++ b/common.c
@@ -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;
+}
diff --git a/common.h b/common.h
index fcf6c53..4786c14 100644
--- a/common.h
+++ b/common.h
@@ -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);
diff --git a/server.c b/server.c
index 7617dfc..787c6dd 100644
--- a/server.c
+++ b/server.c
@@ -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;
+
}
}