-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnewClient.c
212 lines (197 loc) · 6.42 KB
/
newClient.c
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), sendto(), and recvfrom() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#include <sys/mman.h> /* for mmap() */
#include <string.h> /* for string strcpy() and strlen() */
/*Global Variables*/
int userID; /* The user's ID */
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
unsigned short echoServPort; /* Echo server port */
/* Client Message Struct */
struct ClientMessage{
enum {Login, Post, Activate, Subscribe, Unsusbscribe, Logout }
request_Type; /* same size as an unsigned int */
unsigned int UserID; /* unique client identifier */
unsigned int LeaderID; /* unique client identifier */
char message[100]; /* text message */
}; /* an unsigned int is 32 bits = 4 bytes */
/* Server Message Struct */
struct ServerMessage{
unsigned int LeaderID; /* unique client identifier */
char message[100]; /* text message */
}; /* an unsigned int is 32 bits = 4 bytes */
void DieWithError(char *errorMessage); /* External error handling function */
void signIn(); /* Client Signs in */
void signOut(); /* Client Signs Out */
void follow(); /* Client follows a Leader */
void unfollow(); /* Client follows a Leader */
void get_msg(); /* Gets saved messages from server */
void send_msg(); /* Send a message to followers */
void send_to_server(struct ClientMessage *msg); /*Sends the ClientMessage to the server */
void run_client(); /* User Driven Menu To Run Program */
int main(int argc, char *argv[])
{
struct sockaddr_in fromAddr; /* Source address of client */
unsigned int fromSize; /* In-out of address size for recvfrom() */
char servIP[16]; /* IP address of server */
struct ServerMessage server_MSG; /* Buffer for receiving messages from server */
char serverport[10]; /* Port of the server */
/*Prompt user for an ID, Server IP, Port */
printf("Please Enter Your User ID: ");
scanf("%d",&userID);
printf("Your ID is: %d\n",userID);
printf("Please enter the server IP Address: ");
scanf("%s",servIP);
printf("Please enter the server's port number: ");
scanf("%s",serverport);
echoServPort = atoi(serverport); /* Convert user response to int */
/* Create a datagram/UDP socket */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet addr family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
/* Recv a response handled by child node */
fromSize = sizeof(fromAddr);
if (fork() == 0){
int x;
for (;;){
recvfrom(sock, &server_MSG, sizeof(struct ServerMessage), 0,(struct sockaddr *) &fromAddr, &fromSize);
if (echoServAddr.sin_addr.s_addr != fromAddr.sin_addr.s_addr)
{
fprintf(stderr,"Error: received a packet from unknown source.\n");
exit(1);
}
printf("%d said: %s",server_MSG.LeaderID,server_MSG.message);
}
exit(0);
}
/* Signs in user, retrieves stored messages, launches user menu */
signIn();
get_msg();
run_client();
/* closes socket and exits when user quits */
close(sock);
exit(0);
}
/* Signs in client */
void signIn()
{
struct ClientMessage c;
c.request_Type = 0;
c.UserID = userID;
printf("Signing in\n");
send_to_server(&c);
}
/* Client signs Out. */
void signOut()
{
struct ClientMessage c;
c.request_Type = 5;
c.UserID = userID;
printf("Signing out\n");
send_to_server(&c);
}
/* Client follows a Leader. */
void follow()
{
printf("Who would you like to follow:\n");
struct ClientMessage c;
c.request_Type = 3;
c.UserID = userID;
scanf("%d", &c.LeaderID);
printf("You have followed %d\n", c.LeaderID);
send_to_server(&c);
}
/* Client unfollows a Leader */
void unfollow()
{
printf("Who would you like to unfollow:\n");
struct ClientMessage c;
c.request_Type = 4;
c.UserID = userID;
scanf("%d", &c.LeaderID);
printf("You have unfollowed %d\n", c.LeaderID);
send_to_server(&c);
}
/* Request any stored messages from the server */
void get_msg()
{
struct ClientMessage c;
c.request_Type = 2;
c.UserID = userID;
send_to_server(&c);
return;
}
/* Send a message to followers */
void send_msg()
{
struct ClientMessage c;
fseek(stdin,0,SEEK_END); /* Clear stdin */
printf("Enter the message you want to send:\n");
fgets(c.message, 100, stdin);
fseek(stdin,0,SEEK_END); /* Clear stdin */
if(strlen(c.message) >= 100)
{
printf("Your message must be under 100 characters\n");
return;
}
c.UserID = userID;
c.request_Type = 1;
send_to_server(&c);
return;
}
/* This function receives a completed ClientMessage and sends it out to the server */
void send_to_server(struct ClientMessage *msg)
{
/* Send the message to the server */
sendto(sock, msg, sizeof(*msg), 0, (struct sockaddr *) &echoServAddr,
sizeof(echoServAddr));
}
/* runs the user driven menu until the user quits with Sign Out */
void run_client()
{
int selection;
/* Loop with switch statement drives the user interface User keeps entering
options until they quit by signing out */
do
{
printf("Please Select an Option\n");
printf("1-Follow a User\n");
printf("2-Unfollow a User\n");
printf("3-Send Message\n");
printf("4-Sign Out & Quit\n");
scanf("%d",&selection);
switch(selection)
{
case 1: //follow a user
{
follow();
break;
}
case 2: //unfollow a user
{
unfollow();
break;
}
case 3: //Send message
{
send_msg();
break;
}
case 4: //log out
{
signOut();
break;
}
default: //Error for incorrect entries
printf("Your entry is invalid. Please try again\n");
}
}while(selection != 4); /* do until user signs out */
}