-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.c
239 lines (217 loc) · 6.32 KB
/
client.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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
//client.cpp
/*
* g++ -o client client.cpp or make
* ./client <server-ip> port# username
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <netdb.h>
#include <fcntl.h>
#include "duckchat.h"
#define BUFLEN 1024
#define STDIN 0
int connectToSocket(char*, char*);//socket setup
int logUserIn(char*);//send login request and join Common
void sendReqs();//send requests to server
int readMessageType();//reads what type of message recieved from server
int sayMess(struct text_say* rs);
int listMess(struct text_list* rl);
int whoMess(struct text_who* rw);
int errorMess(struct text_error* re);
void err(char*);//error function
struct addrinfo *addrAr;
int sockfd;
int main(int argc, char** argv)
{
//initialize vars
char buf[BUFLEN];
addrAr = NULL;
sockfd = 0;
//error checking correct run input
if(argc != 4)
{
printf("Specify ip port username\n");
exit(0);
}
//call to connect socket and call to send login request to server
connectToSocket(argv[1], argv[2]);
logUserIn(argv[3]);
printf("argv 1: %s argv 2: %s argv 3: %s\n", argv[1], argv[2], argv[3]);
//FD_SET(sockfd, &readfds);//add our socket to our set of files to read from
struct text response;//for testing
while(1)
{
//We want to get array of request structs
//then evaluate request and have different method handle each request
fd_set readfds;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&readfds);//clean set
FD_SET(STDIN, &readfds);//add stdin
//call select to read from stdin if there is input available
if(select(STDIN+1, &readfds, NULL, NULL, &tv) == -1){
perror("select\n");
exit(4);
}//end select
//printf("\nEnter data to send(Type exit and press enter to exit) :");
if(FD_ISSET(STDIN, &readfds))
{
FD_CLR(STDIN, &readfds);
scanf("%[^\n]",buf);
getchar();
if(strcmp(buf,"exit") == 0)
exit(0);
}
int bal = 0;
if(bal = recvfrom(sockfd, buf, BUFLEN, 0,(struct sockaddr*)&addrAr->ai_addr, &addrAr->ai_addrlen) > 0)//if we recieve somthing, print it.
{
printf("recv()'d %d bytes of data in buf\n", bal);
response = (response*) buf;
readMessageType(requests, bal);
}
}
}//end main
void err(char *s)
{
perror(s);
exit(1);
}
int logUserIn(char* user)
{
//send login request to server and then send join common request
printf("logging in...\n");
//setting up structures
struct request_login login;
login.req_type = REQ_LOGIN;
strcpy(login.req_username, user);
struct request_join join;
join.req_type = REQ_JOIN;
strcpy(join.req_channel, "Common");
printf("attempting to send login_req\n");
//sending structs
if (sendto(sockfd, &login, sizeof(login), 0, (struct
sockaddr*)addrAr->ai_addr, addrAr->ai_addrlen)==-1)
err("sendto()");
printf("attempting to send join_req\n");
if (sendto(sockfd, &join, sizeof(join), 0, (struct
sockaddr*)addrAr->ai_addr, addrAr->ai_addrlen)==-1)
err("sendto()");
return true;
}
int connectToSocket(char* ip, char* port)
{
struct addrinfo addressTmp;
struct addrinfo *tmpAdAr;
memset(&addressTmp, 0, sizeof addressTmp);
addressTmp.ai_family = AF_INET;
addressTmp.ai_socktype = SOCK_DGRAM;
int check = 0;
if((check = getaddrinfo(ip, port, &addressTmp, &addrAr))!= 0)
{
err("Client : getaddrinfo() NOT successful\n");
return false;
}
for(tmpAdAr = addrAr; tmpAdAr != NULL; tmpAdAr = tmpAdAr->ai_next)
{
sockfd = socket(tmpAdAr->ai_family, tmpAdAr->ai_socktype, tmpAdAr->ai_protocol);
//sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd == -1)
{
err("Client : socket() NOT successful\n");
continue;
}
break;
}
addrAr = tmpAdAr;
/*int flags = fcntl(sockfd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);*/
fcntl(sockfd, F_SETFL, O_NONBLOCK);//set socket to be non-blocking
printf("socket and bind successful! \n");
return true;
}
int sayMess(text_say *rs)
{
return 0;
}
int listMess(text_list *rl)
{
return 0;
}
int whoMess(text_who *rw)
{
return 0;
}
int errorMess(text_error *re)
{
return 0;
}
int readMessageType(struct text *r, int b) //what type of message have we recieved?
{
int fin = 0;
int netHost = 0;
netHost = ntohl(r->txt_type);
//check if addres is a crazy number or normal
if(netHost > 3 || netHost < 0) {
netHost = r->txt_type;
}
//check if request address is valid
/*if(netHost != 0) {
if(checkValidAddr(r) == -1) {
//bad address, return
cout << "invalid address\n";
return -1;
}
}*/
switch(netHost) {
//printf("the value isss: %s \n", ntohl(r->req_type));
case TXT_SAY:
if(sizeof(struct text_say) == b) {
cout << "say message\n";
fin = sayMess((struct text_say*) r);
break;
} else {
cout << "say message FAILED\n";
break;
}
case TXT_LIST:
if(sizeof(struct text_list) == b) {
cout << "list message\n";
fin = listMess((struct text_list*) r);
break;
} else {
cout << "list message bad size\n";
break;
}
case TXT_WHO:
//printf("join case made \n");
if(sizeof(struct text_who) == b) {
cout << "who message\n";
fin = whoMess((struct text_who*) r);
break;
} else {
cout << "who message bad size\n";
break;
}
case TXT_ERROR:
if(sizeof(struct text_error) == b) {
cout << "error message\n";
fin = errorMess((struct text_error*) r);
break;
} else {
cout << "error message bad size\n";
break;
}
default:
cout << "default case hit!!\n";
}
return fin;
}