/
remote_client.py
108 lines (95 loc) · 2.88 KB
/
remote_client.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
import socket
from struct import *
from greedy_controller import GreedyController
class RemoteClient:
# This class has a lot of code duplication from remote_controller because
# i want it to be standalone
port = 52192
host = "127.0.0.1"
verbs = {
"HelloServer": 1,
"HelloClient": 2,
"Worm": 3,
"Ok": 4,
"Nok": 5,
"Sense": 6,
"Move": 7,
"Kill": 8,
"Bye": 9
}
verb_map = {v: k for k, v in verbs.items()}
def __init__(self, name):
self.name = name
self.controller = GreedyController()
self.finished = False
def start(self):
self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.conn.connect((self.host, self.port))
self.receive()
def send(self, verb_str, data=None):
verb = self.verbs[verb_str]
if data == None: data = b""
length = len(data)
message = pack("<BI", verb, length) + data
self.conn.sendall(message)
def recv(self, length):
return self.conn.recv(length)
def receive(self):
while True:
if self.finished: break
verb = self.conn.recv(1)
if not verb: break
self.handle_message(verb)
def handle_message(self, verb_bt):
verb = unpack("B", verb_bt)[0]
length_bt = self.recv(4)
length = unpack("I", length_bt)[0]
try:
verb_str = self.verb_map[verb]
except KeyError:
verb_str = "Unknown %d" % verb
if verb_str == "HelloServer":
self.handle_hello()
elif verb_str == "Worm":
self.handle_worm()
elif verb_str == "Sense":
self.handle_sense()
elif verb_str == "Kill":
self.handle_kill()
elif verb_str == "Ok":
pass
elif verb_str == "Bye":
self.handle_bye()
else:
self.recv(length)
print("Verb %s not implemented yet" % verb_str)
def handle_worm(self):
data = self.recv(8)
worm_id, dna_len = unpack("II", data)
if dna_len > 0:
dna = self.recv(dna_len)
print("Now controlling worm %d" % worm_id)
self.send("Ok")
def handle_kill(self):
worm_id = unpack("<I", self.recv(4))[0]
print("Worm %d got killed" % worm_id)
def handle_hello(self):
print("Hello from the remote server")
message = pack("B", len(self.name)) + self.name
self.send("HelloClient", message)
def send_move(self, worm_id, direction):
message = pack("<I", worm_id) + direction
self.send("Move", message)
def handle_sense(self):
directions = ['n','e', 's', 'w']
worm_id, num_senses = unpack("<IB", self.recv(5))
senses_bt = self.recv(num_senses)
senses = unpack("%dB" % num_senses, senses_bt)
self.send("Ok")
direction = self.controller.determine_direction(senses)
direction_character = directions[direction]
self.send_move(worm_id, direction_character)
def handle_bye(self):
print("Server said byebye, shutting down")
self.finished = True
RemoteClient("Test client").start()