def run(self): while True: data, addr = self.server.recv() pkg = Packet.unpack(data) # print "got packet: %s, %s, %s" % (pkg.tick, pkg.players, pkg.input) with self.lock: net_tick = self.parent.net_tick if addr not in self.clients: if pkg.tick == 0 and len(pkg.players) == 0 and len(pkg.input) == 0: self.clients[addr] = Client(addr, self.next_id, Player(50 + self.next_id * 30, 50)) self.next_id += 1 pkg_response = Packet(net_tick) pkg_response.add_player(self.clients[addr].id, self.clients[addr].player) self.server.send(pkg_response, addr) print "authenticating new client: %s -> %s" % (addr, self.clients[addr].id) else: print "invalid authentication attempt: %s, %s, %s" % (pkg.tick, pkg.players, pkg.input) else: client = self.clients[addr] client.ack() if pkg.tick >= net_tick: if len(pkg.input) > 0: client.events[pkg.tick] = pkg.input # if net_tick not in self.pkg_queue: # self.pkg_queue[net_tick] = [] # self.pkg_queue[net_tick].insert(0, pkg) else: print "discard packet (too old: %d < %d)" % (pkg.tick, net_tick)
def authenticate(self): """ call this before opening the game gets the current tick from the server and synchronizes the game state """ def threaded_recv(retlist): response, addr = self.client.recv() retlist.append(response) pkg_request = Packet(0) self.client.send(pkg_request) retlist = [] t = Thread(target=lambda: threaded_recv(retlist)) t.daemon = True t.start() wait_start = time.get_ticks() wait_end = wait_start + 1000 while len(retlist) <= 0 and time.get_ticks() < wait_end: time.wait(1) if len(retlist) > 0: response = retlist[0] pkg_response = Packet.unpack(response) self.start_tick = pkg_response.tick if len(pkg_response.players) <= 0: raise RuntimeError("Invalid response: %s" % pkg_response) self.id = pkg_response.players[0][0] self.set_state(pkg_response, backtrack=False) else: raise RuntimeError("Server not responding")
def run(self): while True: data, addr = self.client.recv() try: pkg = Packet.unpack(data) except: print "invalid package from %s" % addr continue with self.lock: self.parent.set_state(pkg, backtrack=True)
def rcv_service(self): while True: if self.state == Conf.SRV_TCP.CLOSE_WAIT: new_pkt = Packet(self.port, self.listener_port, self.seq_no, 0, fin=1) self.state = Conf.SRV_TCP.LAST_ACK self.enq_out(new_pkt) while len(self.in_Q) == 0: sleep(.0003) pkt, ok = Packet.unpack(self.in_Q[0]) rcvd_pkts.info(str(pkt.seq_no)) self.in_lock.acquire() self.in_Q.pop(0) self.in_lock.release() if not ok: continue if self.state == Conf.SRV_TCP.LISTEN: if pkt.syn != 1: continue self.port = pkt.dst_prt self.state = Conf.SRV_TCP.SYN_RCVD self.listener_port = pkt.src_prt # self.seq_no = randint(0, 2 ** 32 - 1) self.seq_no = 0 new_pkt = Packet(pkt.dst_prt, pkt.src_prt, self.seq_no, (pkt.seq_no + 1) % (2**32), syn=1) self.rwnd.expected = pkt.seq_no + 1 self.enq_out(new_pkt) elif self.state == Conf.SRV_TCP.SYN_RCVD: if pkt.ack != 1 or pkt.ack_no != self.seq_no + 1: continue self.seq_no += 1 self.state = Conf.SRV_TCP.ESTAB print "Client", str(self.addr[0]) + ":" + str( self.listener_port), "connected." elif self.state == Conf.SRV_TCP.ESTAB and pkt.fin == 1: self.state = Conf.SRV_TCP.CLOSE_WAIT new_pkt = Packet(pkt.src_prt, pkt.dst_prt, self.seq_no, (pkt.seq_no + 1) % (2**32)) self.enq_out(new_pkt) elif self.state == Conf.SRV_TCP.LAST_ACK: if pkt.ack != 1 or pkt.ack_no != self.seq_no + 1: continue conn_lock.acquire() connected_tcp_conn.remove(self) conn_lock.release() print("Client ", self.addr[0], ":", self.listener_port, " disconnected.") break else: if pkt.seq_no in drop_list: drop_list.remove(pkt.seq_no) continue expected = self.rwnd.new(pkt.seq_no) print "packet", expected, "acked" self.enq_out(Packet(self.port, self.listener_port, 0, expected))
import socket from packet import Packet sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #sock.connect(("68.62.87.97",48011)) sock.connect(("127.0.0.1",8022)) data1={} data2={} data1["request_type"]=3 data1["room"]="Hall" msg1=Packet.pack(data1) data2["request_type"]=4 data2["target"]="room" data2["room"]="Hall" data2["message"]="hello world" msg2=Packet.pack(data2) sock.send("%8s"%(hex(len(msg1))[2:])); sock.send(msg1) sock.send("%8s"%(hex(len(msg2))[2:])); sock.send(msg2) while(1): head = sock.recv(8); if head: size=int("0x"+head.strip(),16); data = sock.recv(size); ary=Packet.unpack(data) print ary
def rcv_service(self): while True: if self.state == Conf.CLT_TCP.TIMED_WAIT: # fixme timed wait self.state = Conf.CLT_TCP.CLOSED print("connection closed.") break while len(self.in_Q) == 0: sleep(.0003) pkt, ok = Packet.unpack(self.in_Q[0]) self.in_lock.acquire() self.in_Q.pop(0) self.in_lock.release() if not ok: continue if self.state == Conf.CLT_TCP.SYN_SENT: if pkt.syn != 1 or pkt.ack != 1 or pkt.ack_no != self.seq_no: continue self.state = Conf.CLT_TCP.ESTAB self.snd_base = self.seq_no self.enq_out( Packet(self.port, self.listener_port, 0, pkt.seq_no + 1)) print("connection established.") elif self.state == Conf.CLT_TCP.FIN_WAIT_1: if pkt.ack != 1 or pkt.ack_no != self.seq_no: continue self.state = Conf.CLT_TCP.FIN_WAIT_2 elif self.state == Conf.CLT_TCP.FIN_WAIT_2: if pkt.fin != 1: continue self.enq_out( Packet(self.port, self.listener_port, 0, pkt.seq_no + 1)) self.state = Conf.CLT_TCP.TIMED_WAIT else: print "++++ packet", pkt.ack_no, "ack received" if pkt.ack_no >= self.snd_base: self.snd_base = pkt.ack_no self.wnd_lock.acquire() try: idx = self.wnd.index(self.snd_base - 1) except ValueError: self.wnd_lock.release() continue self.wnd = self.wnd[idx + 1:] sample_rtt = self.snd_time[idx] - time() self.snd_time = self.snd_time[idx + 1:] clt_rtt_log.info(sample_rtt) self.est_rtt = (1 - self.alpha ) * self.est_rtt + self.alpha * sample_rtt self.dev_rtt = ( 1 - self.beta) * self.dev_rtt + self.beta * abs( sample_rtt - self.est_rtt) # for all received packets # self.wnd_size = self.wnd_size + idx + 1 if self.wnd_size + idx + 1 <= 20 else 20 # for just ack self.wnd_size = self.wnd_size + 1 if self.wnd_size < 20 else 20 clt_cwnd_log.info(self.wnd_size) if len(self.wnd) != 0: self.timer.restart() pass else: self.timer.cancel() pass self.wnd_lock.release()