-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClient.cpp
More file actions
executable file
·167 lines (132 loc) · 3.41 KB
/
Client.cpp
File metadata and controls
executable file
·167 lines (132 loc) · 3.41 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include "Socket.h"
#include <string>
#include <fstream>
#include <sstream>
//#define FILE "lorem_20000.txt"
string getFile(string file) {
ifstream in (file.c_str());
string content(
(istreambuf_iterator<char>(in)),
istreambuf_iterator<char>()
);
return content;
}
void printFile(string file) {
ifstream in (file.c_str());
string content(
(istreambuf_iterator<char>(in)),
istreambuf_iterator<char>()
);
cout << content << endl;
}
void getPacket(int packet, char* message, string content) {
for (int i = 0; i < HEADER; i++) { // fill header
message[i] = 100;
}
int index = packet*CONTENT;
for (int i = 0; i < CONTENT; i++) {
if (index+i < content.length()) {
message[i+HEADER] = content.at(index+i);
}
else {
message[i+HEADER] = '#';
}
}
}
char checkSum(char* message) {
char sum = 0;
for (int i = HEADER; i < BUFFER; i++) {
sum += message[i];
}
if (sum == 0) { // a zero would signify end of array
sum++;
}
return sum;
}
void setSequence(char* message, char sequence) {
message[0] = sequence;
}
void setCheckSum(char* message) {
message[1] = checkSum(message);
}
void setACK(char* message, bool ack) {
message[2] = ack ? 1 : -1;
}
void gremlin(char* message, int packet, Socket sock, const string SERVER, int corrupt, int drop, char sequence) {
bool send = true;
cout << "--------------------" << endl;
cout << "Packet: " << packet << endl;
cout << "Seq: " << sequence << endl;
//cout << packet << ": Seq: " <<sequence << " - Res: ACK" << endl;
if (rand() % 100 < corrupt) {
int random = rand() % 100;
if (random < 10) { // 3 bits damaged
message[6] = rand() % 93 + 33;
}
if (random < 30) { // 2 bits damaged
message[5] = rand() % 93 + 33;
}
message[4] = rand() % 93 + 33; // 1 bit damaged
cout << "Gremlin: Checksum" << endl;
} else if (rand() % 100 < drop) {
cout << "Gremlin: Drop Packet" << endl;
send = false;
}
cout << "Sending ... " << message << endl;
if (send) {
sock.send(SERVER, message);
}
}
int main(int argc, char * argv[]) {
if (argc != 4) {
cout << "Usage: ./client ip corrupt drop" << endl;
exit(1);
}
const string SERVER = argv[1];
//int corrupt = sprintf(argv[2]);
//int drop = stoi(argv[3]);
int corrupt = 0;
int drop = 0;
stringstream(argv[2]) >> corrupt;
stringstream(argv[3]) >> drop;
cout << corrupt << endl;
cout << drop << endl;
char sequence = 'A';
char message[BUFFER];
Socket sock;
int packet = 0;
string file;
cout << "File: PUT ";
cin >> file;
string content = getFile(file);
for (;;) {
getPacket(packet, message, content); // fills content buffer with file
setSequence(message, sequence); // add sequence byte
setCheckSum(message); // calculate and add checkSum
setACK(message, true); // set ACK
gremlin(message, packet, sock, SERVER, corrupt, drop, sequence);
if (sock.receive(true) == -1) { // timeout
cout << "Res: No response, resending" << endl;
} else if (sock.buf[2] == -1) {
if (sequence != sock.buf[0]) { // sequence mismatch
packet++;
sequence = sequence == 'A' ? 'B' : 'A';
cout << "Res: NAK, sequence error, next packet" << endl;
if (message[12] == '#') {
break;
}
} else { // checksum
cout << "Res: NAK, checksum error, resending" << endl;
}
} else {
cout << "Res: ACK" << endl;
sequence = sequence == 'A' ? 'B' : 'A'; // flip sequence
packet++;
if (message[4] == '#') {
break;
}
}
}
printFile(file);
return 0;
}