-
Notifications
You must be signed in to change notification settings - Fork 0
/
headerSplitTest.py
369 lines (303 loc) · 11.9 KB
/
headerSplitTest.py
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
import sys
import re
import time
from socket import *
import select
from Header import Header
import os
import collections
#define global variables
state = 0
fileDict = {}
putFile = ""
#create empty header for use later on
emptyhdr = Header()
emptyhdr.Write()
messageSize = 60
#define constants
serverAddr =('localhost',10000)
#define and create client
clientSocket = socket(AF_INET, SOCK_DGRAM)
clientSocket.setblocking(0)# set blocking to false so timeouts work
#______________________________________________________________________________________________________
#function for gathering inputs
def inputs():
#define global variables
global state
global putFile
#create header to populate request message with
while(1):
datatype = raw_input("GET or PUT a file?\n")
if (datatype == "GET") or (datatype == "PUT"):
break
else:
print "Please input a proper request (GET or PUT)"
while(1):
filename = raw_input("What file do you want/have?\n")
if datatype == "PUT":
if os.path.isfile(filename):
print "Fetching File..."
putFile = filename
break
else:
print "File does not exist. Choose another file..."
if datatype == "GET":
break
print"Processing Request..."
#create instance of header class
request = Header()
#populate it with the input and write a header for the request
request.datatype = datatype
request.options = filename
reqHead = request.Write()
#update state variable
if request.datatype == "GET":
state=1
else:
state=2
#return the header meant to be sent with the request
return state, reqHead
#______________________________________________________________________________________________________
#function for getting file
def getFile(reqHead):
#define global variables
global state
global fileDict
#send request to server
clientSocket.sendto(reqHead, serverAddr)
print "request sent - waiting for response"
#continuously check the socket and handle the mssage storing it to dict
while(1):
#check and read the socket
message=sockRead()
if len(message)==0:
#server lost and get out of function
return
else: #there was a message from the server
#split the header and message up
print "message recieved and ready for interpretation"
#parse message and populate the dictionary
data,index,fileName,messageType = parseMessage(message)
print "data after parse"
print data
print "len of data"
print len(data)
#send an ack back to the server that it got the message
sendAck(index,fileName)
#check to see if EOF - if EOF break then write to file
if len(data) == 0:
print "File Transfer Complete"
saveFile(reqHead)
#clear file Dict for next operation
fileDict = {}
break
#wait for data
#______________________________________________________________________________________________________
def saveFile(reqHead):
global fileDict
print "File Transter complete... Writing File to disk..."
#filename = open(reqHead.options, "w")
filename = open('outputTest.txt', "w")
Keys = fileDict.keys()
Keys.sort()
# keys are strings - change them to integers then sort all of them
intDict = {int(k) : v for k, v in fileDict.items()}
print "sorted"
print intDict
#print sorted(fileDict.keys)
for key in sorted(intDict.iterkeys()):
filename.write(intDict[key])
filename.close()
#print fileDict
print "File saved to disk"
#______________________________________________________________________________________________________
def sendAck(index,fileName):
ack = Header()
#populate it with the sequencenum and file name and ACK message type
ack.datatype = "ACK"
ack.sequencenumber = index
ack.options = fileName
ackHead = ack.Write()
#send just the ACK header
clientSocket.sendto(ackHead, serverAddr)
#______________________________________________________________________________________________________
#function for reading the sockets
def sockRead():
#define global variables
global state
print "waiting to hear from server"
#for reading msgs from server
readSock = [clientSocket]
# empty list since we arent writing to sockets(used in queue
writeSock = []
# empty list - not interested in errors from select
errorSock = []
# time out variable since select has timeout built in
timeout = 1
totalTimeout = 0
#check sockets of server
while(1):
readReady, writeReady, errorReady = select.select(readSock, writeSock, errorSock, timeout)
# if nothing is present in the sockets print a timeout error
if not readReady and not writeReady and not errorReady:
print "timeout: No communication from the server"
print readReady
totalTimeout+=1
if totalTimeout == 5:
state=0 #reset state variable
print "connection to server lost"
message = ""
return message
else:
#something present in the sockets - read it and return it
for socket in readReady: #dont forget to calculate RTT
message, serverAddr = socket.recvfrom(2048)
print "packet recieved..."
return message
#______________________________________________________________________________________________________
def parseMessage(message):
#if server message is an empty msg with no header - total timeout
if len(message) == 0:
return 0,0,0,0
#otherwise handle the file as normal
else:
hdr = Header()
hdr.Write()
print"msg"
print message
headerData = message[:39]
print repr(headerData)
headerdict = hdr.Read(headerData)
#splitMessage = message.split("@")
messageType = headerdict["datatype"]
data = message[40:]
index = headerdict["sequencenumber"]
fileName = headerdict["options"]
#index:message populate file dict
#if data exists its part of the file and should be stored
if len(data) != 0:
fileDict[index] = data
return data, index, fileName, messageType
#______________________________________________________________________________________________________
#function for put file request
def putFile(reqHead):
#define global variables
global state
global fileDict
global putFile
global messageSize
global serverAddr
global emptyhdr
fileDict = {}
#send request to server
messageSend = reqHeader
print "header built. Sending PUT request to server..."
clientSocket.sendto(messageSend, serverAddr)
#wait for ACK regarding request
#check and read the socket
message=sockRead(messageSend)
#if message is recieved split message to hader and data to check ACK
data, index, filename, messageType = parseMessage(message)
#check for ack
if messageType == "ACK":
#open file and break it up into fileDict
print "Server received request. Preparing file for transport..."
#read file and populate dictionary with it
elif (len(message) == 0):
print "Server Timed out. Closing application."
return
#brians way of doing things---------------------------------
#open file and get relevant data out of it for header
FILE = open(putFile, "rb")
filebytes = len(FILE)
filepackets = filebytes/messageSize
packetsize = 100
FILE.close()
# STOP-AND-WAIT needed here: Send file parts
#set up sequence number for sending data
seqNumber = 1
#for i (start at 0) to end of file (i increments by message size
for i in range(0, filebytes+1, msgSize):
#Create data header
dataHDR = Header.Header()
dataHDR.datatype = "DATA"
dataHDR.filesize = str(filebytes)
dataHDR.numberofpackets = str(filepackets)
dataHDR.packetsize = str(packetsize)
dataHDR.timetolive = "5"
dataHDR.options = putFile
dataHDR.sequencenumber = str(seqNumber)
dataheader = dataHDR.Write()
#match data types just incase using dataheader doesnt work
headerBytes = bytearray(dataheader)
# Create the message sequence and join with the header
#fileOBJ = open(filepath)
#open the file > step fid in the file where i is (0 then 60 then 120....)
with open(filepath, "rb") as binary_file:
#Seek to specified position
binary_file.seek(i)
#create message with dataheader and reading msgSize bytes from file
messageSend = dataheader + binary_file.read(messageSize)
# Send message sequence
clientSocketsock.sendto(messageBytes, address)
#STOP-AND-WAIT
serverMessage = sockReadPut(messageSend)
#check if it is an ACK - parse message first
data, index, filename, messageType = parseMessage(message)
#if ack is for correct sequence number increment seq num and start the loop over again
if messageType == "ACK":
seqNumber = seqNumber + 1
#if not ack for correct sequence number restart loop at current sequence number
#if there was a total timeoutleave this loop - check again in the for loop
elif len(serverMessage) == 0:
break
#file closes automatically with with loop type
#if there was a total timeout leave the for loop
if len(serverMessage) == 0:
break
#Send EOF (empty data message with dummt header
sentEOF = sock.sendto(emptyhdr.Write() + "", address)
#-----------------------------------------------------------
#______________________________________________________________________________________________________
def sockReadPut(messageSend):
#define global variables
global state
global serverAddr
print "waiting to hear from server"
#for reading msgs from server
readSock = [clientSocket]
# empty list since we arent writing to sockets(used in queue
writeSock = []
# empty list - not interested in errors from select
errorSock = []
# time out variable since select has timeout built in
timeout = 1
totalTimeout = 0
#check sockets of server
while(1):
readReady, writeReady, errorReady = select.select(readSock, writeSock, errorSock, timeout)
# if nothing is present in the sockets print a timeout error
if not readReady and not writeReady and not errorReady:
print "timeout: No communication from the server, Resending Packet"
#resend message
clientSocket.sendto(messageSend, serverAddr)
totalTimeout+=1
if totalTimeout == 5:
state=0 #reset state variable
print "connection to server lost"
messageRecv = ""
return messageRecv
else:
#something present in the sockets - read it and return it
for socket in readReady: #dont forget to calculate RTT
messageRecv, serverAddr = socket.recvfrom(2048)
print "packet recieved..."
return messageRecv
#______________________________________________________________________________________________________
#asdk for inputs and check program status
state,reqHead = inputs()
print state, reqHead
if state == 1:
getFile(reqHead);
else:
putFile(reqHead);