Detect why a socket closed: FIN vs RST - python

Is it possible to detect why a socket closed in Python, i.e. whether the other side sent a FIN or an RST?
The only way I know to detect if the other side has senta FIN or RST, is to read from the socket, and if you get the empty (byte) string, then we have received either a FIN or an RST. But how to know which one?
import asyncio
import socket
async def async_main(loop):
server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
proto=socket.IPPROTO_TCP)
server_sock.setblocking(False)
server_sock.bind(('', 8080))
server_sock.listen(socket.IPPROTO_TCP)
loop = asyncio.get_event_loop()
sock, adddress = await loop.sock_accept(server_sock)
while True:
data = await loop.sock_recv(sock, 1024)
if data == b'':
# Socket closed, but how?
break
print(data)
loop = asyncio.get_event_loop()
loop.run_until_complete(async_main(loop))

Based on James K Polk's comment, which I believe to be correct, you would distinguish FIN from RST by catching the appropriate exception:
while True:
is_rst = False
try:
data = await loop.sock_recv(sock, 1024)
except IOError as e:
if e.errno == errno.ECONNRESET:
data = b''
is_rst = True
else:
raise
if data == b'':
# Connection closed - use is_rst to distinguish
# between RST and FIN
break
print(data)

Related

create loop to switch from one socket to another

So I have successfully created a socket connection to one client and another, but I am having trouble getting them to switch from one another with loops, did some while true and if statements to make the program recognize when one system wants to switch based on user input but I don't think I'm doing it right. Can some one help me out with a code to switch back and forth
The following is the code I'm attempting to implement.
This is the code on my computer:
import socket,sys,os,time
T2='yourturn'
serverAddr = ('192.168.0.120', 20104)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#client.connect(serverAddr)
sock = client
client.connect(('192.168.0.120', 20104))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def redirectOut(port=20104, host='192.168.0.11'):
"""
connect caller's standard output stream to a socket for GUI to listen
start caller after listener started, else connect fails before accept
"""
sock = client
# caller operates in client mode
file = sock.makefile('w') # file interface: text, buffered
sys.stdout = file
# make prints go to sock.send
return sock
########################################33333
time.sleep(10)
HOST = ''
PORT2 = 20105
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
try:
l=s.bind((HOST, PORT2))
except socket.error as msg:
print('Bind failed. ')
sys.exit()
print('Socket bind complete')
s.listen(10)
print('Socket now listening')
conn, addr = s.accept()
print('Connected to ' + addr[0] + ':' + str(addr[1]))
####################################################
time.sleep(10)
while True:
if T2!='yourturn':
data = conn.recv(1024)
line = data.decode # convert to string (Python 3 only)
T2=print(line)
else :
if T2=='myturn':
break
else:
redirectOut()
T2=print(input())
this is the code on my begalbone black:
import socket
import sys
import os, time
HOST = ''
PORT2 = 20104
T='yourturn'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
try:
l=s.bind((HOST, PORT2))
except socket.error as msg:
print('Bind failed. ')
sys.exit()
print('Socket bind complete')
s.listen(10)
print('Socket now listening')
conn, addr = s.accept()
print('Connected to ' + addr[0] + ':' + str(addr[1]))
#################################################################
time.sleep(15)
serverAddr = ('192.168.0.11', 20105)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = client
try:
sock.connect(('192.168.0.11', 20105))
fsr = 'P9_40'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except TimeoutError:
os.system('reboot')
def redirectOut(port=20105, host='192.168.0.120'):
"""
connect caller's standard output stream to a socket for GUI to listen
start caller after listener started, else connect fails before accept
"""
sock = client
# caller operates in client mode
file = sock.makefile('w') # file interface: text, buffered
sys.stdout = file # make prints go to sock.send
return sock
##############################################################
time.sleep(10)
while True:
if T!='myturn':
data = conn.recv(1024)
line = data.decode('UTF-8') # convert to string (Python 3 only)
T=print(line)
else:
redirectOut()
if T=='yourturn':
break
else:
T=print(input())
So tried this while loop: but its still hanging up, I think I'm close:
T2='yourturn'
while True:
#for line in 'Python':
print(T2)
time.sleep(10)
if T2=='myturn':
data = conn.recv(1024)
line = data.decode
print("myturn print")
l=print(line)
if l=="yourturn":
continue
if T2=="yourturn" or T2!='myturn':
print(T2)
print('myturn send')
redirectOut()# convert to string (Python 3 only)
k=input()
if k=="myturn":
T2='myturn'
continue
Tried the folowing but reciving machine is hanging up when myturn is input:
sending:
time.sleep(3)
T2='yourturn'
print('here')
while True:
#for line in 'Python':
#print(T2)
#time.sleep(10)
if T2=='myturn':
data = conn.recv(1024)
line = data.decode('UTF-8')
#print("myturn print")
l=print(line)
if l=="yourturn":
T2='yourturn'
continue
if T2=="yourturn" and T2!='myturn':
#print(T2)
#print('myturn send')
redirectOut()# convert to string (Python 3 only)
k=input()
print(k)
if k=="myturn":
T2=print('myturn')
T2='myturn'
print('there')
continue
receiving:
time.sleep(3)
T='yourturn'
while True:
#for line in 'Python':
#print(T)
if T=='yourturn':
data = conn.recv(1024)
line = data.decode('UTF-8')
#print("myturn print")
l=print(line)
if l=='myturn':
T='myturn'
continue
if l=='exit':
client.close()
break
if T=='myturn' and T!='yourturn':
#print('myturn send')
redirectOut()# convert to string (Python 3 only)
k=input()
print(k)
if k=='yourturn':
T=print('yourturn')
continue
EDIT SOLUTION:
I finally figured it out, removed my reditectOut function and opened the port with windows firewall to implement this code
my computer:
T2='yourturn'
while True:
if T2=='myturn':
data = conn.recv(1024)
line = data.decode('UTF-8')
print(line)
l=line
if l=="yourturn":
T2='yourturn'
continue
if T2=="yourturn" and T2!='myturn':
k=input()
client.sendto(k.encode('utf-8'),('192.168.0.120', 20104))
if k=="myturn":
T2='myturn'
continue
Beagle bone black:
time.sleep(3)
T='yourturn'
while True:
if T=='yourturn':
data = conn.recv(1024)
line = data.decode('UTF-8')
print(line)
l=line
if l=='myturn':
T='myturn'
continue
if T=='myturn' and T!='yourturn':
k=input()
client.sendto(k.encode('utf-8'),('192.168.0.11', 20105))
if k=='yourturn':
T='yourturn'
continue

I cannot send an ack confirmation from my client after receiving an ACK through socket

I have a server that's always listening and waiting for a connection. When a client connect then sends a file to it, it receives it, saves it and then send back an ACK file, my client send back a confirmation that he received the ACK and finally my server close the connection and my client too.
I had an issue while attempting to receive the ACK from my client, but now it's resolved.
BUT, now that I shutdown my socket connection with SHUT_WR (that's telling that we will stop sending after this, if I'm right) I cannot resend my confirmation.
I can't figure out how that's working and how can I:
From my client
Send a file to my server
Receive the ACK from my server
Resend a confirmation
From my server
Receive a file
Send an ACK
Receive the confirmation
I'm stuck. My server is working unless I try to receive or send something.
The following code blocks are my actual files
client.py
import socket
import os
import random
from socket import SHUT_WR
SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 8192
HOST = "127.0.0.1"
PORT = 8000
files = ["test1.HL7","test2.HL7","test3.HL7","test4.HL7","test5.HL7","test6.HL7","test7.HL7","test8.HL7"]
fileName = f".\\ClientFiles\\{files[random.randrange(1,8)]}"
filesize = os.path.getsize(fileName)
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(f"[+] Connecting to {HOST}:{PORT}")
socket.connect((HOST, PORT))
print("[+] Connected.")
socket.send(f"{fileName}{SEPARATOR}{filesize}".encode())
# opening file
with open(fileName, "rb") as f:
print("[*] Reading")
while True:
# reading bytes
bytes_read = f.read(BUFFER_SIZE)
if not bytes_read:
# Transmitting is done
print("[+] File reading is done.")
break
# send all the buffer
socket.sendall(bytes_read)
print(f"[+] File {fileName} sent")
socket.shutdown(SHUT_WR)
print("[*] Waiting for an acknowledgment")
data = socket.recv(BUFFER_SIZE)
print("[+] Acknoledgment recieved")
print(data.decode())
socket.sendall(data.decode().split('|')[9].encode())
print("[+] Acknowledgment confirmation sent")
print("[*] Closing")
socket.close()
server.py
import itertools
import socket
import signal
import ntpath
from pathlib import Path
from consts import *
from helper import *
# Setting Dicionnaries for HL7 ACK Requirements
MSH = {0:'MSH',2:'', 3:'', 4:'', 5:'', 6:'', 7:'', 8:'', 9:'', 10:'', 11:'',12:'', 13:'', 14:'', 15:'NE', 16:'AL', 17:'', 18:'', 19:'', 20:'', 21:''}
MSA = {0:'MSA', 1:'AA', 2:''}
ACK = {'MSH':{}, 'MSA':{}}
def hl7_ack_generator():
"""Generate the Acknowledgement file and sends it to the client
Returns:
String: Returns the Acknowledgment filename
"""
content = ""
# Switch sender-receiver
MSH[3], MSH[5], MSH[4], MSH[6] = MSH[5], MSH[3], MSH[6], MSH[4]
# Set the message type.
# If possible get the message trigger to return the same trigger
try:
MSH[9] = f"ACK^{check_msh_9_trigger_event(MSH[9].decode().split('^'))}^ACK"
except:
MSH[9] = "ACK"
# Set MSH values
for param in MSH:
ACK['MSH'][param] = MSH.get(param)
# Set MSA values
for param in MSA:
ACK['MSA'][param] = MSA.get(param)
# Create the ACK message
# Handle integers & bytes in each fields
# Get MSH values
for i in range(0,21) :
if i != 1:
if ACK['MSH'][i]:
# Generate a message id based on recieved message timestamp and message id
# not exceeding 20 chars
if i == 10:
ACK['MSH'][10] = ACK['MSH'][7].decode() + ACK['MSH'][10].decode()
if len(ACK['MSH'][10]) > 20:
ACK['MSH'][10] = ACK['MSH'][10][:20]
content += ACK['MSH'][10]
else:
try:
content += ACK['MSH'][i].decode()
except:
if not ACK['MSH'][i] == None:
content += ACK['MSH'][i]
content += '|'
content += "\r"
# Get MSA values
for i in range(0,3):
try:
content += ACK['MSA'][i].decode()
except:
if not ACK['MSA'][i] == None:
content += ACK['MSA'][i]
content += "|"
# Create the ACK filename
filename = ACK['MSH'][10] + "_ACK.HL7"
# create the ACK file and write its content
with open(Path(SERVER_ACK_FILES_FOLDER + filename), "w") as f:
f.write(content)
f.close()
return filename
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# test the binding
try:
socket.bind((SERVER_HOST, SERVER_PORT))
except socket.error as error:
print('Bind failed. Error Code : '
+ str(error[0]) + ' Message '
+ error[1])
exit()
# Handle ctrl+c
def signal_handler(sign, frame):
print('[*] Shutting down')
exit(0)
while signal.signal(signal.SIGINT, signal_handler):
# connection limit(5 connection try then deny)
socket.listen(5)
print(f"[*] Listening as {SERVER_HOST}:{SERVER_PORT}")
# accept the connection if there is any
client_socket, address = socket.accept()
# Below code is executed if sender is connected
print(f"[+] {address} is connected.")
# get what the client is sending
received = client_socket.recv(BUFFER_SIZE)
filename, bytes_read = received.split(SEPARATOR.encode())
# get the file size
fileSize = bytes(itertools.takewhile(lambda i: bytes((i,)).isdigit(), bytes_read))
bytes_read = bytes_read[len(fileSize):]
#convert to integer
fileSize = int(fileSize)
filename = filename.decode()
# remove absolute path if there is
filename = ntpath.basename(filename)
# start receiving the file from the socket and writing to the file stream
with open(Path(SERVER_FILES_FOLDER + filename), "wb") as f:
print("[+] File received")
while True:
# write to the file the bytes we just received
f.write(bytes_read)
# read 1024 bytes from the socket (receive)
bytes_read = client_socket.recv(BUFFER_SIZE)
if bytes_read.startswith(b'MSH'):
messageHeader = bytes_read.partition(b'\r')[0].split(b'|')
j = 0
i = 2
for i in range(2,17):
j+=1
# Exclude MSH fields(constant and/or unwanted)
if i not in (15,16):
MSH[i]= messageHeader[j]
#Get message ID
if i == 10:
MSA[2] = messageHeader[j]
ackFilename = hl7_ack_generator()
if not bytes_read:
# file transmitting is done
print("[+] File transfert is done")
break
with open(Path(SERVER_ACK_FILES_FOLDER + ackFilename), "rb") as f:
while True:
bytes_read = f.read(BUFFER_SIZE)
if not bytes_read:
print("[+] Acknoledgment Sent")
break
client_socket.sendall(bytes_read)
confirmation = client_socket.recv(BUFFER_SIZE)
print(confirmation)
print("[+] Confirmation received")
print("[*] Closing conneciton")
client_socket.close()
socket.close
testX.hl7
MSH|^~\&|ADT1|MCM|LABADT|MCM|198808181126|SECURITY|ADT^A04|MSG00001|P|2.4
EVN|A01-|198808181123
PID|||PATID1234^5^M11||JONES^WILLIAM^A^III||19610615|M-||2106-3|1200 N ELM STREET^^GREENSBORO^NC^27401-1020|GL|(919)379-1212|(919)271-3434~(919)277-3114||S||PATID12345001^2^M10|123456789|9-87654^NC
NK1|1|JONES^BARBARA^K|SPO|||||20011105
NK1|1|JONES^MICHAEL^A|FTH
PV1|1|I|2000^2012^01||||004777^LEBAUER^SIDNEY^J.|||SUR||-||1|A0-
AL1|1||^PENICILLIN||PRODUCES HIVES~RASH
AL1|2||^CAT DANDER
DG1|001|I9|1550|MAL NEO LIVER, PRIMARY|19880501103005|F||
PR1|2234|M11|111^CODE151|COMMON PROCEDURES|198809081123
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^SMITH^ELLEN|199505011201
GT1|1122|1519|BILL^GATES^A
IN1|001|A357|1234|BCMD|||||132987
IN2|ID1551001|SSN12345678
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^ELLEN|199505011201
Thanks for the attention!
I changed my server into this:
final_size = b''
while True:
# write to the file the bytes we just received
f.write(bytes_read)
final_size += bytes_read
if len(final_size) >= fileSize:
# file transmitting is done
print("[+] File transfert is done")
break
# read 1024 bytes from the socket (receive)
bytes_read = client_socket.recv(BUFFER_SIZE)
if bytes_read.startswith(b'MSH'):
messageHeader = bytes_read.partition(b'\r')[0].split(b'|')
j = 0
i = 2
for i in range(2,17):
j += 1
# Exclude MSH fields(constant and/or unwanted)
if i not in (15,16):
MSH[i]= messageHeader[j]
#Get message ID
if i == 10:
MSA[2] = messageHeader[j]
ackFilename = hl7_ack_generator()
And my client to this:
print(f"[+] File {fileName} sent")
print("[*] Waiting for an acknowledgment")
data = sock.recv(BUFFER_SIZE)
print("[+] Acknoledgment recieved")
sock.sendall(data.decode().split('|')[9].encode())
print("[+] Acknowledgment confirmation sent")
print("[*] Closing")
sock.close()

How to make a socket server run forever without closed itself (Python)

Whenever the client disconnect, the server will close itself. How can i make the server to run forever ?
What i'm doing
The server let one client to retrieve files with no issues. But the problem is when the client close the program, the server will also closed itself and wouldn't let another client to establish the connection . I had read a few articles about using while loops to make the session alive. Does anyone know how can I do that ?
Server.py
import socket, os, subprocess, shutil, pickle, struct
# Create a Socket ( connect two computers)
def create_socket():
try:
global host
global port
global s
host = ""
port = 9999
s = socket.socket()
except socket.error as msg:
create_socket()
# Binding the socket and listening for connections
def bind_socket():
try:
global host
global port
global s
s.bind((host, port))
s.listen(5)
except socket.error as msg:
bind_socket()
# send file list
def flist(conn):
try:
arr = pickle.dumps(os.listdir())
conn.send(arr)
except:
conn.send(('Error').encode("utf-8"))
# accept file from server
def fdown(filename, conn):
try:
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
f.close()
except:
conn.send(('Error').encode("utf-8"))
# send file
def fup(filename, conn):
if os.path.isfile(filename):
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
else:
conn.send("ERROR".encode("utf-8"))
# main
def main(s):
while True:
data = (s.recv(1024)).decode("utf-8").split('~')
if data[0] == 'fdown':
fup(data[1], s)
elif data[0] == 'fup':
fdown(data[1], s)
elif data[0] == 'flist':
flist(s)
else:
s.send(".".encode('utf-8'))
# Establish connection with a client (socket must be listening)
def socket_accept():
conn, address = s.accept()
main(conn)
conn.close()
create_socket()
bind_socket()
socket_accept()
You should put accept in the loop, and you may need use a thread to handle read
sample code:
def handle_read(s):
while True:
data = s.recv(1024)
if not data:
#When the client closed, recv will return an empty data
s.close()
break
data = data.decode("utf-8").split('~')
if data[0] == 'fdown':
fup(data[1], s)
elif data[0] == 'fup':
fdown(data[1], s)
elif data[0] == 'flist':
flist(s)
else:
s.send(".".encode('utf-8'))
def socket_accept():
while True:
conn, address = s.accept()
t = threading.Thread(target = handle_read, args=(conn, ))
t.start()

tcp lost packet python [duplicate]

This question already exists:
TCP socket python
Closed 2 years ago.
i am using tcp socket for forwarding data (as class with type of request, and data) between server and client. When i send 6 object of order from client, the server get only 5 object of order, 1 is lost, but tcp is reliable protocol... (sometimes the server get 6 but usually get 5) my question is why an object lost in forwarding by tcp?
Here's the client code
PORT = 3000
SIZE = 4096
HOST = '127.0.0.1'
soc = None
ing_map = None
def connect_to_client():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
global soc
soc = s
def send_object(data):
if soc is None:
raise NotImplementedError # There is no connection
else:
# make data as bytes
msg = pickle.dumps(data)
msg = bytes(f"{len(msg):<{HEADERSIZE}}", 'utf-8') + msg
print(sys.getsizeof(msg))
soc.send(msg)
def get_object(req):
if soc is None:
raise NotImplementedError # There is no connection
else:
# unpickle the data
send_object(req)
if soc is None:
raise NotImplementedError # There is no connection
else:
# unpickle the data
data = b''
while True:
part = soc.recv(SIZE)
data += part
if len(part) < SIZE:
break
full_msg = data
try:
data = pickle.loads(full_msg[HEADERSIZE:])
except EOFError:
data = None
return data
def send_order(order):
if order is not None:
send_object(Soc_request(Request.P_ORDER,order))
def main():
global ing_map
connect_to_client()
ing_map = get_object(Soc_request(Request.G_ING_MAP, None))
#send order
burger = Burger(ing_map)
salad = Salad(ing_map)
burger.add_ingredient('ham')
o1 = Order(Priority.NORMAL)
o2 = Order(Priority.NORMAL)
o3 = Order(Priority.VIP)
o4 = Order(Priority.VIP)
o5 = Order(Priority.PLUS)
o6 = Order(Priority.PLUS)
o1.meals_lst.append(burger)
o1.meals_lst.append(burger)
o1.meals_lst.append(burger)
o3.meals_lst.append(burger)
send_order(o1)
send_order(o2)
send_order(o3)
send_order(o4)
send_order(o5)
send_order(o6)
soc.close()
Here's the server code
HOST = '127.0.0.1'
PORT = 3000
SIZE = 1000
HEADERSIZE = 10
WORKERS = 2
conn = None
addr = None
soc = None
order_m = None
def create_connection():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
global conn, addr
global soc
soc = s
conn, addr = s.accept()
def send_object(data):
if soc is None:
raise NotImplementedError # There is no connection
else:
# make data as bytes
global conn
msg = pickle.dumps(data)
msg = bytes(f"{len(msg):<{HEADERSIZE}}", 'utf-8') + msg
conn.send(msg)
def get_object():
global conn
if conn is None:
raise NotImplementedError # There is no connection
else:
# unpickle the data
data = b''
while True:
part = conn.recv(SIZE)
data += part
if len(part) < SIZE:
break
full_msg = data
try:
data = pickle.loads(full_msg[HEADERSIZE:])
except EOFError:
data = None
return data
def main():
create_connection()
# Initialize objects
global order_m
ing_map = Ingredient_map()
order_m = OrderManager()
while True:
msg = get_object()
if msg is None:
pass
elif msg.req == Request.G_ING_MAP: # get ingredient map
send_object(ing_map.instance.map)
elif msg.req == Request.P_ORDER:
order_m.add_order(msg.data)
print(msg.data)
# end while
soc.close()
if __name__ == "__main__":
main()
The output of the server is
order 0
order 1
order 3
order 4
order 5
but order 2 lost!
why? what should i fix that all the orders will arrive ?
Request is an enum for request type.
Let's visualize the 6 pickled objects on their way from the client to the server:
server <- 1112222233334445555566 <- client
A TCP connection is one stream of data. There are no boundaries. The server has to split the data to individual parts and unpickle each part:
111 22222 3333 444 55555 66
In order to be able to do that, you must introduce some high level structure to the data. I can't run your code, but I don't see anything like that there. Instead the server just reads into a fixed size buffer. The reality is little bit complicated, but I think this is sometimes happening:
1112 2222 3333 4445 5555 66
The objects 1, 3, 4 and 6 were transferred in one piece, but 2 and 5 were divided into two parts and these parts cannot be separately unpickled.
I think you need to put the length of the pickled data to the header. Then the server should first read the header (fixed size), extract the length and then read and unpickle as many following bytes (not less, not more).
Also this fragment:
try:
data = pickle.loads(full_msg[HEADERSIZE:])
except EOFError:
data = None
hides errors. Do not blame TCP for losing packets when you silently discard data.
As #VPfB mentioned, you are sending the header size but never parsing the size. You really should restructure your code, however, here is a working example using your code.
In your client code, change your get_object function to this.
def get_object(req):
if soc is None:
raise NotImplementedError # There is no connection
else:
# unpickle the data
send_object(req)
if soc is None:
raise NotImplementedError # There is no connection
else:
# unpickle the data
# this initial recv only receives the header length
length = int(soc.recv(HEADERSIZE).decode('utf-8'))
data = b''
while True:
# here we receive a minimum of the standard recv size
# and the diff between your already received data
# and the full length, whichever is smaller
part = soc.recv(min(SIZE, length - len(data)))
data += part
# if the length that was specifed in the header has been received
# we know we have everything
if length == len(data):
break
full_msg = data
try:
data = pickle.loads(full_msg)
except EOFError:
data = None
return data
Now we'll make almost identical changes in your server code.
def get_object():
global conn
if conn is None:
raise NotImplementedError # There is no connection
else:
# unpickle the data
# the only difference here is
# when we receive nothing, we know it's time to wait for another connect
length = conn.recv(HEADERSIZE).decode('utf-8')
if len(length):
length = int(length)
data = b''
while True:
part = conn.recv(min(SIZE, length - len(data)))
data += part
if length == len(data):
break
full_msg = data
try:
data = pickle.loads(full_msg)
except EOFError:
data = None
return data
else:
# wait for another connection
conn, addr = soc.accept()
In reality a server typically behaves like this:
# do this forever
while True:
# wait for an incoming connection
conn, addr = soc.accept()
# get the length of the data the connection is sending
length = int(soc.recv(HEADERSIZE).decode('utf-8'))
# get the data
data = b''
while True:
part = soc.recv(min(SIZE, length - len(data)))
data += part
if length == len(data):
break
# do some stuff with the data
The difference is we wait for a fresh connection after each object received. This gives other clients attempting to connect a turn as well.

How to flush/clear buffer in a socket in python3

How do I flush a socket in python3?
I'm looking to do something like this
def clear_buffer(sock):
try:
while sock.recv(1024): pass
except:
pass
or
def clear_buffer(sock):
while True:
data = sock.recv(1024)
if not data:
break
After attempting to run these two functions neither seem to break the while loop and/or flush out the socket from incoming data. How do I conditionally do something when the socket has stopped receiving data?
while run_network:
recv = True
data = b''
try:
while recv:
try:
packet = socket.recv(10240)
if packet:
data += packet
else:
recv = False
try:
pickle.loads(data)
recv = False
except:
recv = True
except ConnectionResetError:
print(f"{client} has disconnected........")
break
except ConnectionError:
**strong text**
print(f"{client}has a Connection Error.....")
break

Categories

Resources