Python - 客户端有时从不接收数据
Python - Client sometimes never receives data
我正在制作一个 client/server 小游戏。虽然它看起来大部分都在工作,但服务器和客户端之间的通信似乎有点奇怪,我不太确定是什么原因造成的。
因此,我启动 server.py
,然后启动 client.py
,客户端连接并接收第一条消息的长度,它接收实际消息并完美显示。但是当它再次运行时,它永远不会得到第二条消息,只有它有多长。它只是无限期地等待(好吧,我猜是 TCP 超时持续时间)。
我知道有些字节可能会丢失,但 TCP 旨在保证在仍有连接的情况下传送,对吗? UDP 是那种只丢弃数据包的协议吗?它似乎也没有断开连接。这也在本地主机上,所以它甚至没有离开我的机器。
以防与时间有关,在等待客户端用户输入的回复之前,我还制作了服务器 time.sleep(.5)
。
尽管使用相同的方法发送,为什么客户端收到第一条消息却收不到第二条消息?
Server.py
import socket, random, pickle, os.path, csv, time
# Global variables
c = 0
a = ""
def SendIt(d):
global c
d = pickle.dumps(d)
MSGLEN = len(d)
print ("MSGLEN =", MSGLEN) # REMOVE AFTER DEBUG
MSGLENstr = pickle.dumps(MSGLEN)
c.send(MSGLENstr)
totalsent = 0
while totalsent < MSGLEN:
sent = c.send(d[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
def TheMainGame():
def within(val, goal):
i = abs(val - goal)
if (i <= 3):
return True
else:
return False
def try_int(k):
try:
return int(k)
except ValueError:
return k
def GetScoreboard():
with open('Scores.csv', 'r') as scores:
reader = csv.reader(scores)
tscores = [[str(e) for e in r] for r in reader if len(r) > 0]
return tscores
def WriteScore(gscore):
global c, a, tscore
exists = os.path.isfile("Scores.csv")
if (exists == False): # Checks if file exists, if not create it
nscore = [[gscore, a[0]]] # Add first line of data
with open("Scores.csv", "a") as scores:
writer = csv.writer(scores)
[writer.writerow(r) for r in nscore]
else: # File exists so we add to it
nscore = [[gscore, a[0]]]
with open('Scores.csv', 'r') as scores:
reader = csv.reader(scores)
tscores = [[str(e) for e in r] for r in reader if len(r) > 0]
tscores = [[try_int(l) for l in i] for i in tscores]
tscores.append(nscore[0])
tscores = [x for x in tscores if x != []]
tscores.sort(key=lambda x: x[0])
if (len(tscores) > 5):
tscores = tscores[:5]
with open("Scores.csv", "w+") as scores:
writer = csv.writer(scores)
[writer.writerow(r) for r in tscores]
elif (len(tscores) <= 5):
with open("Scores.csv", "w+") as scores:
writer = csv.writer(scores)
[writer.writerow(r) for r in tscores]
def Guess():
global c
guesses = 0
while True:
data = ["open", "What is your guess?"]
SendIt(data)
time.sleep(.5)
print("sent question") # REMOVE AFTER DEBUG
t = int(c.recv(1000).decode())
print("waiting for reply") # REMOVE AFTER DEBUG
if (t == x):
guesses += 1
data = ["msg","Correct!"]
SendIt(data)
if (guesses == 1):
msg = "You took ", guesses, " guess!"
else:
msg = "You took ", guesses, " guesses!"
msg = [str(x) for x in msg]
msg = ",".join(msg)
msg = msg.replace(",", "")
data = ["msg", msg]
SendIt(data)
WriteScore(guesses)
data = ["msg", "Heres the leaderboard:"]
SendIt(data)
data = ["scores", GetScoreboard()]
SendIt(data)
data = ["closing", "Thanks for playing!"]
SendIt(data)
c.close()
break
elif (within(t,x) == True):
guesses += 1
data = ["incorrect", "Close!"]
SendIt(data)
elif (within(t,x) == False):
guesses += 1
data = ["incorrect", "Far"]
SendIt(data)
else:
data = ["closing", "There was an error computing the value"]
SendIt(data)
c.close()
break
x = random.randrange(1, 20, 1)
print(x) # REMOVE AFTER DEBUG
Guess()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 4001))
s.listen(5)
while True:
(c,a) = s.accept()
data = ["msg", "Hello user!"]
SendIt(data)
TheMainGame()
Client.py
import socket, pickle
# Global variables
connected = False
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data = ["closing", "Connection closed"]
def GetData():
global s, data
chunks = []
bytes_recd = 0
MSGLEN = s.recv(512) # OLD RECV
MSGLEN = pickle.loads(MSGLEN)
print ("MSGLEN =", MSGLEN) # REMOVE AFTER DEBUG
while bytes_recd < MSGLEN:
chunk = s.recv(min(MSGLEN - bytes_recd, 2048))
print("chunk =", chunk) # REMOVE AFTER DEBUG
if chunk == b'':
raise RuntimeError("socket connection broken")
chunks.append(chunk)
bytes_recd = bytes_recd + len(chunk)
data = b''.join(chunks)
data = pickle.loads(data)
print("data after depickled=", data) # REMOVE AFTER DEBUG
def SendData():
global s
sdata = input()
s.send(sdata.encode())
def Connect():
global s, connected
s.connect(("127.0.0.1", 4001))
connected = True
# Connect to server
Connect()
# Send/recive data till session ends
while (connected == True):
print("fetching data") # REMOVE AFTER DEBUG
GetData()
print ("got data") # REMOVE AFTER DEBUG
if (data[0] == "closing"):
print (data[1])
s.close()
connected = False
break
elif (data[0] == "incorrect"):
print (data[1])
elif (data[0] == "open"):
print("open task running") # REMOVE AFTER DEBUG
print (data[1])
print("printed data[1]") # REMOVE AFTER DEBUG
SendData()
elif (data[0] == "msg"):
print (data[1])
elif (data[0] == "scores"):
data = data[1]
data = [",".join(i) for i in data]
data = [i.replace(",", " - ") for i in data]
print("Guesses - User")
print(*data, sep='\n')
else:
print ("An error occured!")
服务器输出
MSGLEN = 36
5
MSGLEN = 45
sent question
客户端输出
fetching data
MSGLEN = 36
chunk = b'\x80\x03]q\x00(X\x03\x00\x00\x00msgq\x01X\x0b\x00\x00\x00Hello user!q\x02e.'
data after depickled= ['msg', 'Hello user!']
got data
Hello user!
fetching data
MSGLEN = 45
完成后服务器不会有任何输出,我只是为了帮助调试而输入的。而且客户端中的大部分输出也不存在,同样只是用于调试。我用 # REMOVE AFTER DEBUG
标记了所有调试行,以帮助更容易找到它们。如您所见,chunk = s.recv(min(MSGLEN - bytes_recd, 2048))
从未完成第二次。
这是我自己解决的基于逻辑的错误。
我删除了服务器中的 time.sleep(.5)
行并将其向上移动到 SendIt()
并将其更改为 time.sleep(.1)
导致服务器在将数据发送到客户端之前休眠 0.1 秒.透视:
def Guess():
global c
guesses = 0
while True:
data = ["open", "What is your guess?"]
SendIt(data)
"""time.sleep(.5)""" # This line gets removed
print("sent question")
t = int(c.recv(1000).decode())
print("waiting for reply")
和
def SendIt(d):
global c
d = pickle.dumps(d)
MSGLEN = len(d)
print ("MSGLEN =", MSGLEN)
MSGLENstr = pickle.dumps(MSGLEN)
time.sleep(.1) # This new line makes it pause 0.1 seconds before sending the data
c.send(MSGLENstr)
totalsent = 0
while totalsent < MSGLEN:
sent = c.send(d[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
希望这对其他人有帮助!还记得import time
.
我正在制作一个 client/server 小游戏。虽然它看起来大部分都在工作,但服务器和客户端之间的通信似乎有点奇怪,我不太确定是什么原因造成的。
因此,我启动 server.py
,然后启动 client.py
,客户端连接并接收第一条消息的长度,它接收实际消息并完美显示。但是当它再次运行时,它永远不会得到第二条消息,只有它有多长。它只是无限期地等待(好吧,我猜是 TCP 超时持续时间)。
我知道有些字节可能会丢失,但 TCP 旨在保证在仍有连接的情况下传送,对吗? UDP 是那种只丢弃数据包的协议吗?它似乎也没有断开连接。这也在本地主机上,所以它甚至没有离开我的机器。
以防与时间有关,在等待客户端用户输入的回复之前,我还制作了服务器 time.sleep(.5)
。
尽管使用相同的方法发送,为什么客户端收到第一条消息却收不到第二条消息?
Server.py
import socket, random, pickle, os.path, csv, time
# Global variables
c = 0
a = ""
def SendIt(d):
global c
d = pickle.dumps(d)
MSGLEN = len(d)
print ("MSGLEN =", MSGLEN) # REMOVE AFTER DEBUG
MSGLENstr = pickle.dumps(MSGLEN)
c.send(MSGLENstr)
totalsent = 0
while totalsent < MSGLEN:
sent = c.send(d[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
def TheMainGame():
def within(val, goal):
i = abs(val - goal)
if (i <= 3):
return True
else:
return False
def try_int(k):
try:
return int(k)
except ValueError:
return k
def GetScoreboard():
with open('Scores.csv', 'r') as scores:
reader = csv.reader(scores)
tscores = [[str(e) for e in r] for r in reader if len(r) > 0]
return tscores
def WriteScore(gscore):
global c, a, tscore
exists = os.path.isfile("Scores.csv")
if (exists == False): # Checks if file exists, if not create it
nscore = [[gscore, a[0]]] # Add first line of data
with open("Scores.csv", "a") as scores:
writer = csv.writer(scores)
[writer.writerow(r) for r in nscore]
else: # File exists so we add to it
nscore = [[gscore, a[0]]]
with open('Scores.csv', 'r') as scores:
reader = csv.reader(scores)
tscores = [[str(e) for e in r] for r in reader if len(r) > 0]
tscores = [[try_int(l) for l in i] for i in tscores]
tscores.append(nscore[0])
tscores = [x for x in tscores if x != []]
tscores.sort(key=lambda x: x[0])
if (len(tscores) > 5):
tscores = tscores[:5]
with open("Scores.csv", "w+") as scores:
writer = csv.writer(scores)
[writer.writerow(r) for r in tscores]
elif (len(tscores) <= 5):
with open("Scores.csv", "w+") as scores:
writer = csv.writer(scores)
[writer.writerow(r) for r in tscores]
def Guess():
global c
guesses = 0
while True:
data = ["open", "What is your guess?"]
SendIt(data)
time.sleep(.5)
print("sent question") # REMOVE AFTER DEBUG
t = int(c.recv(1000).decode())
print("waiting for reply") # REMOVE AFTER DEBUG
if (t == x):
guesses += 1
data = ["msg","Correct!"]
SendIt(data)
if (guesses == 1):
msg = "You took ", guesses, " guess!"
else:
msg = "You took ", guesses, " guesses!"
msg = [str(x) for x in msg]
msg = ",".join(msg)
msg = msg.replace(",", "")
data = ["msg", msg]
SendIt(data)
WriteScore(guesses)
data = ["msg", "Heres the leaderboard:"]
SendIt(data)
data = ["scores", GetScoreboard()]
SendIt(data)
data = ["closing", "Thanks for playing!"]
SendIt(data)
c.close()
break
elif (within(t,x) == True):
guesses += 1
data = ["incorrect", "Close!"]
SendIt(data)
elif (within(t,x) == False):
guesses += 1
data = ["incorrect", "Far"]
SendIt(data)
else:
data = ["closing", "There was an error computing the value"]
SendIt(data)
c.close()
break
x = random.randrange(1, 20, 1)
print(x) # REMOVE AFTER DEBUG
Guess()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 4001))
s.listen(5)
while True:
(c,a) = s.accept()
data = ["msg", "Hello user!"]
SendIt(data)
TheMainGame()
Client.py
import socket, pickle
# Global variables
connected = False
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data = ["closing", "Connection closed"]
def GetData():
global s, data
chunks = []
bytes_recd = 0
MSGLEN = s.recv(512) # OLD RECV
MSGLEN = pickle.loads(MSGLEN)
print ("MSGLEN =", MSGLEN) # REMOVE AFTER DEBUG
while bytes_recd < MSGLEN:
chunk = s.recv(min(MSGLEN - bytes_recd, 2048))
print("chunk =", chunk) # REMOVE AFTER DEBUG
if chunk == b'':
raise RuntimeError("socket connection broken")
chunks.append(chunk)
bytes_recd = bytes_recd + len(chunk)
data = b''.join(chunks)
data = pickle.loads(data)
print("data after depickled=", data) # REMOVE AFTER DEBUG
def SendData():
global s
sdata = input()
s.send(sdata.encode())
def Connect():
global s, connected
s.connect(("127.0.0.1", 4001))
connected = True
# Connect to server
Connect()
# Send/recive data till session ends
while (connected == True):
print("fetching data") # REMOVE AFTER DEBUG
GetData()
print ("got data") # REMOVE AFTER DEBUG
if (data[0] == "closing"):
print (data[1])
s.close()
connected = False
break
elif (data[0] == "incorrect"):
print (data[1])
elif (data[0] == "open"):
print("open task running") # REMOVE AFTER DEBUG
print (data[1])
print("printed data[1]") # REMOVE AFTER DEBUG
SendData()
elif (data[0] == "msg"):
print (data[1])
elif (data[0] == "scores"):
data = data[1]
data = [",".join(i) for i in data]
data = [i.replace(",", " - ") for i in data]
print("Guesses - User")
print(*data, sep='\n')
else:
print ("An error occured!")
服务器输出
MSGLEN = 36
5
MSGLEN = 45
sent question
客户端输出
fetching data
MSGLEN = 36
chunk = b'\x80\x03]q\x00(X\x03\x00\x00\x00msgq\x01X\x0b\x00\x00\x00Hello user!q\x02e.'
data after depickled= ['msg', 'Hello user!']
got data
Hello user!
fetching data
MSGLEN = 45
完成后服务器不会有任何输出,我只是为了帮助调试而输入的。而且客户端中的大部分输出也不存在,同样只是用于调试。我用 # REMOVE AFTER DEBUG
标记了所有调试行,以帮助更容易找到它们。如您所见,chunk = s.recv(min(MSGLEN - bytes_recd, 2048))
从未完成第二次。
这是我自己解决的基于逻辑的错误。
我删除了服务器中的 time.sleep(.5)
行并将其向上移动到 SendIt()
并将其更改为 time.sleep(.1)
导致服务器在将数据发送到客户端之前休眠 0.1 秒.透视:
def Guess():
global c
guesses = 0
while True:
data = ["open", "What is your guess?"]
SendIt(data)
"""time.sleep(.5)""" # This line gets removed
print("sent question")
t = int(c.recv(1000).decode())
print("waiting for reply")
和
def SendIt(d):
global c
d = pickle.dumps(d)
MSGLEN = len(d)
print ("MSGLEN =", MSGLEN)
MSGLENstr = pickle.dumps(MSGLEN)
time.sleep(.1) # This new line makes it pause 0.1 seconds before sending the data
c.send(MSGLENstr)
totalsent = 0
while totalsent < MSGLEN:
sent = c.send(d[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
希望这对其他人有帮助!还记得import time
.