-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclientServerHandler.c
More file actions
148 lines (130 loc) · 5.49 KB
/
clientServerHandler.c
File metadata and controls
148 lines (130 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdint.h>
#include "networks.h"
#include "safeUtil.h"
#include "PDUTransmit.h"
#include "clientServerHandler.h"
#include "pollLib.h"
//functions for handling each flag of message from the server
void recvBroadcast(struct PDUMsg* msg);
void recvMultiCast(struct PDUMsg* msg);
void recvInvalidHandler(struct PDUMsg* msg);
void recvHandlerCount(struct PDUMsg* msg);
void recvHandlerList(int socketNo, struct PDUMsg* msg);
void enableInputs(void);
//parse a message from the server. redirect to apprioriate handle function based on its flag
void parseServerMsg(int socketNo, struct PDUMsg* msg){
switch (msg->flag) {
case FLAG_BROADCAST_MESSAGE:
recvBroadcast(msg);
break;
case FLAG_DIRECT_MESSAGE:
recvMultiCast(msg); //direct and MultiCast message format are the same
break;
case FLAG_MULTICAST_MESSAGE:
recvMultiCast(msg);
break;
case FLAG_INVALID_HANDLE:
recvInvalidHandler(msg);
break;
case FLAG_SEND_LIST_COUNT:
recvHandlerCount(msg); //prints the handler counts and disables input from STDIn
break;
case FLAG_SEND_LIST_ENTRY:
recvHandlerList(socketNo,msg);
break;
case FLAG_SEND_LIST_DONE:
enableInputs(); //re-enable inputs from STDIn
break;
default:
printf("\rWarning, Unrecognized Flag, disregarding msg\n");
break;
}
//add parsing stuff to take actions. for not just print what we recieved
}
//recieves a broadcast message (on FLAG_BROADCAST_MESSAGE)
void recvBroadcast(struct PDUMsg* msg){
int dataIndex=0; //iterate over message
uint8_t sendingHandleLen=(msg->data)[dataIndex]; //first index is the sending Handlers Length
dataIndex+=sizeof(sendingHandleLen);
char sendingHandle[101]={0};
memcpy(sendingHandle,(msg->data)+dataIndex, sendingHandleLen); //followed by the sender handler name
dataIndex+=sendingHandleLen;
//followed by the message, which is printed here:
printf("\r%s: %s\n", sendingHandle, msg->data + dataIndex);
}
//recieves a multicast or unicast message (on FLAG_MULTICAST_MESSAGE or FLAG_DIRECT_MESSAGE)
// (its one function since these have the same format)
//prints the handler name who sent it, followed by the message
void recvMultiCast(struct PDUMsg* msg){
int dataIndex=0; //iterate over message
uint8_t sendingHandleLen=(msg->data)[dataIndex]; //first index is the sending Handlers Length
dataIndex+=sizeof(sendingHandleLen);
char* sendingHandle=(char*)((msg->data)+dataIndex); //followed by the sender handler name
dataIndex+=sendingHandleLen; //skip over sendersHandle
uint8_t numSenders=(msg->data)[dataIndex]; //followed by how many targets this message is for
msg->data[dataIndex]='\0'; //null terminate sendingHandle, so it can be prints
dataIndex+=sizeof(numSenders);
//skip over information about who this message was sent too. We do not print it
for(int i=0;i<numSenders;i++){ //skip over recipient handlers
uint8_t recipientLen=(msg->data)[dataIndex];
dataIndex+=recipientLen + sizeof(recipientLen);
}
//we are now at the text segment of message. Print that along with the snedingHandle :)
printf("\r%s: %s\n", sendingHandle, msg->data + dataIndex);
}
//Response from the server if we try to send a message to a client that doesnt exist (FLAG_INVALID_HANDLE)
//prints a warning to the user
void recvInvalidHandler(struct PDUMsg* msg){
char targHeader[maxHandleLen+1]={0};
uint8_t targHeaderLen=msg->data [0];
memcpy(targHeader, (msg->data )+1, targHeaderLen);
printf("\rClient with handle %s does not exist\n", targHeader);
}
//recieves the number of clients connected to the server (on FLAG_SEND_LIST_COUNT)
//prints this value, and disables user input while we wait for their names
void recvHandlerCount(struct PDUMsg* msg){
uint16_t h_msgLen= ntohs(msg->nw_length);
if(h_msgLen!=7){
printf("\rwarning: server message for number of clients had invalid length. ignoring this message. This should never happen\n");
return;
}
uint32_t nw_numClients;
memcpy(&nw_numClients,msg->data,sizeof(uint32_t));
uint32_t h_numClients=ntohl(nw_numClients);
printf("\rnumber of Clients: %d\n", h_numClients);
removeFromPollSet(STDIN_FILENO); //disable user inputs for now
}
//recieve a name of a given handler (on FLAG_SEND_LIST_ENTRY)
//print the entry name with an indent
void recvHandlerList(int socketNo, struct PDUMsg*msg){
uint16_t h_msgLen= ntohs(msg->nw_length);
if(h_msgLen<5){
printf("\rwarning: server message for client name is too short to contain a handler. ignoring this message. This should never happen\n");
return;
}
uint8_t handlerLen=msg->data [0];
if(handlerLen+DataOffset+sizeof(handlerLen) != h_msgLen){
printf("\rWarning, contradictory info for lengths of client handlers. ignoring this message. This should never happen\n");
return;
}
msg->data [h_msgLen-DataOffset]='\0'; //Null terminate our string
printf(" %s\n", msg->data);
}
//re-enable inputs after finish recieving handlerList (on FLAG_SEND_LIST_DONE)
void enableInputs(){
addToPollSet(STDIN_FILENO);
fflush(stdout);
}