close() and disconnect()
parent
18c0f7d03a
commit
b7c30d1491
58
mods/utcp.py
58
mods/utcp.py
|
@ -208,7 +208,6 @@ class TCP(object):
|
||||||
raise EOFError('Connection not in connected devices')
|
raise EOFError('Connection not in connected devices')
|
||||||
data_parts = TCP.data_divider(data)
|
data_parts = TCP.data_divider(data)
|
||||||
for data_part in data_parts:
|
for data_part in data_parts:
|
||||||
data_not_received = True
|
|
||||||
data_chunk = data_part if not self.encrypted else self.peer_keypair[connection].peer_pub.encrypt_raw(data_part)
|
data_chunk = data_part if not self.encrypted else self.peer_keypair[connection].peer_pub.encrypt_raw(data_part)
|
||||||
checksum_of_data = TCP.checksum(data_chunk)
|
checksum_of_data = TCP.checksum(data_chunk)
|
||||||
self.connections[connection].checksum = checksum_of_data
|
self.connections[connection].checksum = checksum_of_data
|
||||||
|
@ -217,26 +216,28 @@ class TCP(object):
|
||||||
packet_to_send = pickle.dumps(self.connections[connection])
|
packet_to_send = pickle.dumps(self.connections[connection])
|
||||||
self.connections[connection].checksum = 0
|
self.connections[connection].checksum = 0
|
||||||
self.connections[connection].data = b''
|
self.connections[connection].data = b''
|
||||||
retransmit_count = 0
|
answer = self.retransmit(connection, packet_to_send)
|
||||||
while data_not_received and retransmit_count < 3:
|
|
||||||
data_not_received = False
|
|
||||||
try:
|
|
||||||
self.own_socket.sendto(packet_to_send, connection)
|
|
||||||
answer = self.find_correct_packet('ACK', connection)
|
|
||||||
if not answer:
|
|
||||||
data_not_received = True
|
|
||||||
retransmit_count += 1
|
|
||||||
except socket.timeout:
|
|
||||||
#print('timeout')
|
|
||||||
data_not_received = True
|
|
||||||
if not answer:
|
|
||||||
self.drop_connection(connection)
|
|
||||||
raise EOFError('Connection lost')
|
|
||||||
self.connections[connection].seq += len(data_part)
|
self.connections[connection].seq += len(data_part)
|
||||||
return len(data)
|
return len(data)
|
||||||
except socket.error as error:
|
except socket.error as error:
|
||||||
raise EOFError('Socket was closed before executing command. Error is: %s.' % error)
|
raise EOFError('Socket was closed before executing command. Error is: %s.' % error)
|
||||||
|
def retransmit(self, peer_addr, pickled_packet, condition='ACK'):
|
||||||
|
data_not_received = True
|
||||||
|
retransmit_count = 0
|
||||||
|
while data_not_received and retransmit_count < 3:
|
||||||
|
data_not_received = False
|
||||||
|
try:
|
||||||
|
self.own_socket.sendto(pickled_packet, peer_addr)
|
||||||
|
answer = self.find_correct_packet(condition, peer_addr)
|
||||||
|
if not answer:
|
||||||
|
data_not_received = True
|
||||||
|
retransmit_count += 1
|
||||||
|
except socket.timeout:
|
||||||
|
data_not_received = True
|
||||||
|
if not answer:
|
||||||
|
self.drop_connection(peer_addr)
|
||||||
|
raise EOFError('Connection lost')
|
||||||
|
return answer
|
||||||
def recv(self, size, connection=None):
|
def recv(self, size, connection=None):
|
||||||
try:
|
try:
|
||||||
if connection not in list(self.connections.keys()):
|
if connection not in list(self.connections.keys()):
|
||||||
|
@ -379,13 +380,13 @@ class TCP(object):
|
||||||
fin_packet.set_flags(fin=True)
|
fin_packet.set_flags(fin=True)
|
||||||
packet_to_send = pickle.dumps(fin_packet)
|
packet_to_send = pickle.dumps(fin_packet)
|
||||||
self.own_socket.sendto(packet_to_send, connection)
|
self.own_socket.sendto(packet_to_send, connection)
|
||||||
answer = self.find_correct_packet('ACK', connection) # change cause may get a None value
|
answer = self.retransmit(connection, packet_to_send)
|
||||||
conn.ack += 1
|
conn.ack += 1
|
||||||
answer = self.find_correct_packet('FIN-ACK', connection)
|
answer = self.find_correct_packet('FIN-ACK', connection)
|
||||||
if answer.flag_fin != 1:
|
if answer.flag_fin != 1:
|
||||||
raise Exception('The receiver didn\'t send the fin packet')
|
raise Exception('The receiver didn\'t send the fin packet')
|
||||||
else:
|
else:
|
||||||
self.send_ack(connection, self.connections[connection].ack + 1)
|
self.send_ack(connection, conn.ack + 1)
|
||||||
self.drop_connection(connection)
|
self.drop_connection(connection)
|
||||||
if len(self.connections) == 0 and self.client:
|
if len(self.connections) == 0 and self.client:
|
||||||
self.own_socket.close()
|
self.own_socket.close()
|
||||||
|
@ -395,16 +396,15 @@ class TCP(object):
|
||||||
|
|
||||||
def disconnect(self, connection):
|
def disconnect(self, connection):
|
||||||
try:
|
try:
|
||||||
self.connections[connection].ack += 1
|
conn = self.connections[connection]
|
||||||
self.connections[connection].seq += 1
|
self.send_ack(connection, conn.set_ack(conn.ack + 1))
|
||||||
self.connections[connection].set_flags(ack=True)
|
finack_packet = TCPPacket(conn.seq_inc())
|
||||||
packet_to_send = pickle.dumps(self.connections[connection])
|
finack_packet.set_flags(fin=True, ack=True)
|
||||||
self.own_socket.sendto(packet_to_send, connection)
|
packet_to_send = pickle.dumps(finack_packet)
|
||||||
self.connections[connection].set_flags(fin=True, ack=True)
|
try:
|
||||||
self.connections[connection].seq += 1
|
answer = self.retransmit(connection, packet_to_send)
|
||||||
packet_to_send = pickle.dumps(self.connections[connection])
|
except:
|
||||||
self.own_socket.sendto(packet_to_send, connection)
|
pass
|
||||||
answer = self.find_correct_packet('ACK', connection)
|
|
||||||
with self.connection_lock:
|
with self.connection_lock:
|
||||||
self.connections.pop(connection)
|
self.connections.pop(connection)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
|
Loading…
Reference in New Issue