Skip to content

Commit 1544344

Browse files
emaicusbmcutler
authored andcommitted
Changed Tutorial 16 from ping pong to zig zag (#25)
1 parent 21c4a13 commit 1544344

28 files changed

+615
-1516
lines changed

examples/16_docker_network_python/config/config.json

Lines changed: 223 additions & 99 deletions
Large diffs are not rendered by default.
Lines changed: 42 additions & 257 deletions
Original file line numberDiff line numberDiff line change
@@ -1,281 +1,66 @@
11
#!/usr/bin/env python3
22
import socket
33
import os
4-
import csv
54
import sys
65
import time
6+
import json
77
import traceback
8+
import threading
9+
import argparse
810

911
MY_NAME = ""
10-
KNOWN_HOSTS_TCP = 'knownhosts_tcp.txt'
11-
KNOWN_HOSTS_UDP = 'knownhosts_udp.txt'
12-
USE_UDP = False
13-
14-
15-
# This tutorial is kept simple intentionally rather than using data structures or
16-
# dictionaries to store these values.
17-
server_name = ""
18-
19-
incoming_tcp_port = 0
20-
outgoing_tcp_port = 1
21-
incoming_udp_port = 2
22-
outgoing_udp_port = 3
23-
24-
outgoing_tcp_socket = None
25-
incoming_tcp_socket = None
26-
open_tcp_connection = None
27-
28-
outgoing_udp_socket = None
29-
incoming_udp_socket = None
30-
31-
32-
33-
def init():
34-
read_known_hosts_csv()
35-
initialize_incoming_connections()
36-
12+
KNOWN_HOSTS_JSON = 'knownhosts.json'
13+
ADDRESS_BOOK = dict()
3714

3815
#knownhosts_tcp.csv and knownhosts_udp.csv are of the form
3916
#sender,recipient,port_number
4017
# such that sender sends all communications to recipient via port_number.
41-
def read_known_hosts_csv():
42-
global server_name
43-
global incoming_tcp_port, outgoing_tcp_port
44-
global incoming_udp_port, outgoing_udp_port
18+
def read_known_hosts_json():
19+
global ADDRESS_BOOK, MY_NAME
20+
with open(KNOWN_HOSTS_JSON) as infile:
21+
content = json.load(infile)
4522

46-
with open(KNOWN_HOSTS_TCP) as infile:
47-
content = infile.readlines()
48-
49-
for line in content:
50-
sender, recv, port = line.split()
51-
if sender == MY_NAME:
52-
outgoing_tcp_port =port
53-
server_name = recv
54-
elif recv == MY_NAME:
55-
incoming_tcp_port = port
56-
server_name = sender
57-
else:
58-
continue
59-
60-
if USE_UDP:
61-
with open(KNOWN_HOSTS_UDP) as infile:
62-
content = infile.readlines()
63-
64-
for line in content:
65-
sender, recv, port = line.split()
66-
if sender == MY_NAME:
67-
outgoing_udp_port =port
68-
server_name = recv
69-
elif recv == MY_NAME:
70-
incoming_udp_port = port
71-
server_name = sender
72-
else:
73-
continue
74-
75-
def initialize_incoming_connections():
76-
global incoming_tcp_socket, incoming_udp_socket
77-
incoming_tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
78-
server_address = ('', int(incoming_tcp_port))
79-
incoming_tcp_socket.bind(server_address)
80-
incoming_tcp_socket.listen(5)
81-
incoming_tcp_socket.setblocking(False)
82-
print('Listening on port {0} for incoming tcp connections'.format(incoming_tcp_port))
83-
84-
if USE_UDP:
85-
incoming_udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
86-
incoming_udp_socket.setblocking(False)
87-
server_address = ('', int(incoming_udp_port))
88-
incoming_udp_socket.bind(server_address)
89-
print('Listening on port {0} for incoming udp connections'.format(incoming_udp_port))
90-
91-
def init_outgoing_connection(connection_type):
92-
global outgoing_tcp_socket, outgoing_tcp_port
93-
global outgoing_udp_socket, outgoing_udp_port
94-
95-
if connection_type == 'tcp':
96-
if outgoing_tcp_socket != None:
97-
return True
98-
server_address = (server_name, int(outgoing_tcp_port))
99-
outgoing_tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
100-
try:
101-
outgoing_tcp_socket.connect(server_address)
102-
return True
103-
except Exception as e:
104-
print('Unable to connect on {0} (tcp)'.format(server_address))
105-
traceback.print_exc()
106-
return False
107-
elif connection_type == 'udp':
108-
if outgoing_udp_socket != None:
109-
return True
110-
server_address = (server_name, int(outgoing_udp_port))
111-
outgoing_udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
112-
return True
113-
return False
23+
for host, info in content['hosts'].items():
24+
tcp_port = info['tcp_start_port']
25+
udp_port = info['udp_start_port']
11426

27+
if host == MY_NAME:
28+
continue
29+
else:
30+
ADDRESS_BOOK[host] = {'udp_port' : udp_port, 'tcp_port' : tcp_port }
11531

11632

117-
def send_out_message(msg, tcp=True):
118-
global outgoing_tcp_socket, outgoing_udp_socket
119-
if tcp and outgoing_tcp_socket == None:
120-
print("ERROR! Could not establish outgoing tcp connection to {0}".format(server_name))
121-
sys.exit(1)
122-
elif tcp == False and outgoing_udp_socket == None:
123-
print("ERROR! Could not establish outgoing udp connection to {0}".format(server_name))
124-
sys.exit(1)
33+
def main():
34+
read_known_hosts_json()
12535

36+
stdin = input('')
37+
parts = stdin.split('-')
38+
next_host = parts[0]
39+
next_message = ':'.join(parts[1:])
40+
next_message += ':FINISHED!'
41+
next_message = next_message.encode('utf-8')
12642

127-
if tcp:
128-
print("Sending '{0}' to {1}".format(msg, server_name, outgoing_tcp_port))
129-
sys.stdout.flush()
130-
outgoing_tcp_socket.sendall(msg.encode('utf-8'))
131-
else:
132-
sys.stdout.flush()
133-
destination_address = (server_name, int(outgoing_udp_port))
134-
outgoing_udp_socket.sendto(msg.encode('utf-8'),destination_address)
135-
136-
def cleanup():
137-
print("Cleaning up after myself.")
138-
global incoming_tcp_socket, outgoing_tcp_socket, open_tcp_connection, outgoing_udp_socket, incoming_udp_socket
139-
if incoming_tcp_socket != None:
140-
incoming_tcp_socket.close()
141-
if outgoing_tcp_socket != None:
142-
outgoing_tcp_socket.close()
143-
if open_tcp_connection != None:
144-
open_tcp_connection.close()
145-
if USE_UDP:
146-
if outgoing_udp_socket != None:
147-
outgoing_udp_socket.close()
148-
if incoming_udp_socket != None:
149-
incoming_udp_socket.close()
150-
151-
def check_for_request(tcp_allowed=True):
152-
global open_tcp_connection, incoming_tcp_socket, incoming_udp_socket
153-
154-
if tcp_allowed:
155-
try:
156-
if open_tcp_connection == None:
157-
open_tcp_connection, client_address = incoming_tcp_socket.accept()
158-
open_tcp_connection.setblocking(False)
159-
160-
message = open_tcp_connection.recv(1024)
161-
return message.decode('utf-8')
162-
except BlockingIOError as e:
163-
#print("Exception encountered. Shouldn't be a big deal.")
164-
#traceback.print_exc()
165-
pass
166-
except Exception as e:
167-
print(traceback.format_exc())
168-
169-
if USE_UDP:
170-
try:
171-
message = incoming_udp_socket.recv(1024)
172-
return message.decode('utf-8')
173-
except socket.error:
174-
pass
175-
except Exception as e:
176-
print(traceback.format_exc())
177-
178-
return None
179-
180-
def delay_seconds(secs=.5):
181-
time.sleep(secs)
182-
183-
def send_message_and_wait_for_response(message,tcp=True):
184-
connection_type = 'tcp' if tcp else 'udp'
185-
while not init_outgoing_connection(connection_type):
43+
# First, try udp:
44+
try:
45+
outgoing_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
46+
addr = (next_host, ADDRESS_BOOK[next_host]['udp_port'])
47+
outgoing_socket.sendto(next_message, addr)
48+
except Exception as e:
18649
pass
18750

188-
send_out_message(message,tcp)
189-
190-
response = None
191-
while response == None:
192-
response = check_for_request()
193-
time.sleep(.1)
194-
print("Recieved '{0}' from {1}".format(response, server_name))
195-
sys.stdout.flush()
196-
197-
def just_send_message(message,tcp=True):
198-
connection_type = 'tcp' if tcp else 'udp'
199-
while not init_outgoing_connection(connection_type):
51+
#Then, try tcp
52+
try:
53+
outgoing_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
54+
outgoing_socket.connect((next_host, ADDRESS_BOOK[next_host]['tcp_port']))
55+
outgoing_socket.sendall(next_message)
56+
except Exception as e:
20057
pass
201-
send_out_message(message,tcp)
202-
203-
def auto_run_zero():
204-
delay_seconds(1)
205-
send_message_and_wait_for_response('ping')
206-
207-
def auto_run_one():
208-
delay_seconds(1)
209-
send_message_and_wait_for_response('ping')
210-
send_message_and_wait_for_response('ping')
211-
212-
def auto_run_two():
213-
send_message_and_wait_for_response('not ping')
214-
215-
def auto_run_three():
216-
send_message_and_wait_for_response('not ping')
217-
send_message_and_wait_for_response('ping')
218-
send_message_and_wait_for_response('ping')
219-
220-
def auto_run_four():
221-
print("We are sending messages to the server...")
222-
just_send_message('ping',tcp=False,)
223-
just_send_message('not ping',tcp=False)
224-
just_send_message('ping',tcp=False)
225-
just_send_message('not ping',tcp=False)
226-
just_send_message('not ping',tcp=False)
227-
just_send_message('ping',tcp=False)
228-
just_send_message('ping',tcp=False)
229-
230-
responses = []
231-
for count in range(7):
232-
delay_seconds()
233-
#We don't want tcp responses.
234-
response = check_for_request(tcp_allowed=False)
235-
if response != None:
236-
responses.append(response)
237-
pongs = 0
238-
not_pongs = 0
239-
for response in responses:
240-
if response == "pong":
241-
pongs += 1
242-
else:
243-
not_pongs += 1
244-
245-
if pongs > 0:
246-
print("We sent 4 pings to the server...")
247-
print('We recieved some pongs! It looks like the student was using UDP!'.format(pongs))
248-
if not_pongs > 0:
249-
print("We sent 3 'not pings' to the server...")
250-
print('We recieved some "not pongs!" It looks like the student was using UDP!'.format(not_pongs))
251-
252-
253-
if __name__ == "__main__":
254-
if len(sys.argv) < 3:
255-
print("ERROR: Please pass the following arguments:\n\t1: The name of this host in the knownhosts.csv file.\n\t3:The name of the run you want to do.")
256-
sys.stdout.flush()
257-
sys.exit(1)
258-
MY_NAME = sys.argv[1]
259-
RUN_NAME = sys.argv[2]
260-
261-
if len(sys.argv) > 3:
262-
if sys.argv[3].strip() == 'udp_enabled':
263-
USE_UDP=True
264-
init()
265-
266-
if RUN_NAME == "0":
267-
auto_run_zero()
268-
elif RUN_NAME == "1":
269-
auto_run_one()
270-
elif RUN_NAME == "2":
271-
auto_run_two()
272-
elif RUN_NAME == "3":
273-
auto_run_three()
274-
elif RUN_NAME == "4":
275-
auto_run_four()
276-
277-
cleanup()
278-
print('Shutting down.')
27958

59+
if __name__ == '__main__':
60+
MY_NAME = socket.gethostname()
61+
try:
62+
main()
63+
except KeyboardInterrupt:
64+
sys.exit(0)
28065

28166

0 commit comments

Comments
 (0)