-
Notifications
You must be signed in to change notification settings - Fork 0
/
sender.cpp
136 lines (122 loc) · 3.79 KB
/
sender.cpp
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
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
#include "csapp.h"
#include "message.h"
#include "connection.h"
#include "client_util.h"
void checkLoginJoinResponse(Message msg);
int send_loop(Connection &conn, Message send);
void receive_loop(Connection &conn, Message response);
int main(int argc, char **argv) {
if (argc != 4) {
std::cerr << "Usage: ./sender [server_address] [port] [username]\n";
return 1;
}
std::string server_hostname;
int server_port;
std::string username;
server_hostname = argv[1];
server_port = std::stoi(argv[2]);
username = argv[3];
Connection conn;
// TODO: connect to server
conn.connect(server_hostname, server_port);
// TODO: send slogin message
Message slogin = Message(TAG_SLOGIN, username); //receeuver sends rlogin
conn.send(slogin);
Message slogin_response; //the rlogin response sends back by the server
conn.receive(slogin_response); //receive the message
checkLoginJoinResponse(slogin_response); //check if response is valid format
// TODO: loop reading commands from user, sending messages to
// server as appropriate
Message send;
Message response;
while (true){
int quit = send_loop(conn, send); //send messages to server
if(quit == 2){ //start again if user message is invalid
continue;
}
receive_loop(conn, response); //react to messages sent back from the server
if(quit == 1){ //if user commands quit, stop the loop and return
break;
}
}
return 0;
}
/* function to check whether the reponse of the login message is valid
Parameter:
msg: the login response message
*/
void checkLoginJoinResponse(Message msg) {
if (msg.tag == TAG_ERR) { //if tag is ERR
std::cerr << msg.data.c_str(); //print the rlogin failed message to cerr
exit(1);
}
if (msg.tag != TAG_OK) { //if tag is not OK,
std::cerr << "Other error in login response";
exit(1);
}
}
/* function for the sender to send commands and message
Parameter:
conn: current connection object
send: message object that will be edited and sent to the server
Return:
quit: 0 means normal, continue the loop
1 means quit, stop the loop and exit
2 means invalid user message, end this loop and start over
*/
int send_loop(Connection &conn, Message send){
int quit = 0;
std::string input;
std::getline(std::cin, input);
std::stringstream ssinput(input);
std::string tag;
ssinput >> tag; // identify the tag of the input
std::string msg;
if (tag[0] == '/') { // process input if it is a command
if (tag.compare("/join") == 0) {
ssinput >> msg;
send = {TAG_JOIN, msg};
} else if (tag.compare("/leave") == 0) {
send = {TAG_LEAVE, "bye"};
} else if (tag.compare("/quit") == 0) {
send = {TAG_QUIT, "bye"};
quit = 1;
} else { // if tag does not match any expected value, start over
fprintf(stderr, "%s\n", "invalid command");
quit = 2;
return quit;
}
} else { // if not command, treat input line as message
send = {TAG_SENDALL, ssinput.str()};
}
if (!conn.send(send)) { // send message to server
std::cerr << "cannot send message to server";
exit(1);
}
return quit;
}
/* function for the sender to receive a message from the server
Parameter:
conn: current connection object
response: message object that is sent from the server
*/
void receive_loop(Connection &conn, Message response){
if (conn.receive(response)) {
if (response.tag == TAG_ERR) {
std::cerr << response.data.c_str();
} else if (response.tag != TAG_OK) {
std::cerr << "unexpected server response tag";
}
} else {
if (!conn.is_open()) {
std::cerr << "unable to receive due to EOF or Error";
exit(1);
} else {
std::cerr << "unable to receive due to invalid format";
}
}
}