-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient1.py
125 lines (103 loc) · 3.79 KB
/
client1.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
#!/usr/bin/python
# This is the CS 352 Spring 2017 Client for the 1st programming
# project
import argparse
import time
import struct
import md5
import os
import sock352
def main():
# parse all the arguments to the client
parser = argparse.ArgumentParser(description='CS 352 Socket Client')
parser.add_argument('-f','--filename', help='File to Send', required=False)
parser.add_argument('-d','--destination', help='Destination IP Host', required=True)
parser.add_argument('-p','--port', help='remote sock352 port', required=False)
parser.add_argument('-u','--udpportRx', help='UDP port to use for receiving', required=True)
parser.add_argument('-v','--udpportTx', help='UDP port to use for sending', required=False)
# get the arguments into local variables
args = vars(parser.parse_args())
filename = args['filename']
destination = args['destination']
udpportRx = args['udpportRx']
if (args['udpportTx']):
udpportTx = args['udpportTx']
else:
udpportTx = ''
# the port is not used in part 1 assignment, except as a placeholder
if (args['port']):
port = args['port']
else:
port = 1111
# open the file for reading
if (filename):
try:
filesize = os.path.getsize(filename)
fd = open(filename, "rb")
usefile = True
except:
print ( "error opening file: %s" % (filename))
exit(-1)
else:
pass
# This is where we set the transmit and receive
# ports the client uses for the underlying UDP
# sockets. If we are running the client and
# server on the same machine, these ports
# need to be different. If they are running on
# different machines, we can re-use the same
# ports.
if (udpportTx):
sock352.init(udpportTx,udpportRx)
else:
sock352.init(udpportRx,udpportRx)
# create a socket and connect to the remote server
s = sock352.socket()
s.connect((destination,port))
# send the size of the file as a 4 byte integer
# to the server, so it knows how much to read
FRAGMENTSIZE = 8192
longPacker = struct.Struct("!L")
fileLenPacked = longPacker.pack(filesize)
s.send(fileLenPacked)
# use the MD5 hash algorithm to validate all the data is correct
mdhash = md5.new()
# loop for the size of the file, sending the fragments
bytes_to_send = filesize
start_stamp = time.clock()
while (bytes_to_send > 0):
fragment = fd.read(FRAGMENTSIZE)
mdhash.update(fragment)
totalsent = 0
# make sure we sent the whole fragment
while (totalsent < len(fragment)):
sent = s.send(fragment[totalsent:])
if (sent == 0):
raise RuntimeError("socket broken")
totalsent = totalsent + sent
bytes_to_send = bytes_to_send - len(fragment)
end_stamp = time.clock()
lapsed_seconds = end_stamp - start_stamp
# this part send the lenght of the digest, then the
# digest. It will be check on the server
digest = mdhash.digest()
# send the length of the digest
long = len(digest)
digestLenPacked = longPacker.pack(long)
sent = s.send(digestLenPacked)
if (sent != 4):
raise RuntimeError("socket broken")
# send the digest
sent = s.send(digest)
if (sent != len(digest)):
raise RuntimeError("socket broken")
if (lapsed_seconds > 0.0):
print ("client1: sent %d bytes in %0.6f seconds, %0.6f MB/s " % (filesize, lapsed_seconds,
(filesize/lapsed_seconds)/(1024*1024)))
else:
print ("client1: sent %d bytes in %d seconds, inf MB/s " % (filesize, lapsed_seconds))
fd.close()
s.close()
# this gives a main function in Python
if __name__ == "__main__":
main()