我一直在处理的代码似乎不允许连接,或返回错误,或做任何事情。我无法弄清楚什么是错的,因为没有错误被抛出。任何人都可以帮我调试。客户端应该在按钮单击时发送文本,服务器只接收并打印消息。正如我所说,该程序运行,但没有打印任何东西,并没有做任何事情后显示错误或问题所以我无法确定如何解决它。任何帮助将不胜感激。
import sys, os, time, socket, tkinter
from tkinter import *
HOST = ''
PORT = 31337
BUFF = 4096
DATA = [8000]
CNCT = 5
NAME = ''
ADDRESS_LIST = []
try:
SOCK = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Failed to create socket')
sys.exit()
class CLIENT():
def __init__(self):
self.h = 'localhost'
self.p = 31337
self.t = 'HELLO!'
top = tkinter.Tk()
top.geometry('400x200')
top.title('CHAT WITH ME!')
self.host = tkinter.Entry(top)
self.host.place(x=37,y=25)
self.host.bind('<Key-Return>',self.ret_host())
self.port = tkinter.Entry(top)
self.port.place(x=200,y=25)
self.port.bind('<Key-Return>',self.ret_port())
self.text = tkinter.Entry(top)
self.text.place(x=110,y=50)
self.text.bind('<Key-Return>',self.ret_text())
but1 = tkinter.Button(top, text ="send", command = self.buttonClick())
but1.place(x=0,y=20)
mb = Menu(tkinter.Menu(), tearoff=0)
lt = len(ADDRESS_LIST)
#mb.add_checkbutton(label="FRIEND" + str(lt), variable = ADDRESS_LIST[lt-1])
top.mainloop()
def ret_host(self):
self.h = self.host.get()
def ret_port(self):
self.p = self.port.get()
def ret_text(self):
self.t = self.text.get()
def buttonClick(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if self.p == '':
self.p = 31337
else:
port = int(self.p)
if self.h == '':
self.h = 'localhost'
ADDRESS_LIST.append(self.h)
try:
sock.connect((self.h, port))
sock.sendall(bytes(self.t,'ascii'))
except:
print('connection refused')
finally:
sock.close()
class SERVER():
conn = ''
addr = 'localhost'
data = ''
trth = False
host = ''
port = ''
def __init__(self):
SOCK.bind((HOST, PORT))
SOCK.listen(CNCT)
def New_Thread(self):
sock = SOCK
self.conn, self.addr = sock.accept()
if self.addr == '':
trth = False
print(self.addr)
else:
print('Got connection from ', self.addr)
self.rcvr()
trth = True
def rcvr(self):
data = self.conn.recv(BUFF)
if not data:
print('no data')
else:
#ADDRESS_LIST.append(self.addr)
#print(len(ADDRESS_LIST))
print(str(self.addr) + '> ', data)
SRV = SERVER()
SRV.New_Thread()
CLIENT()
答案 0 :(得分:3)
这里有三个主要问题,还有一些较小的问题。
首先,正如丹尼尔罗斯曼所说,只是调用方法New_Thread
并不会神奇地使它成为线程。
但这很容易解决。您可以这样做,而不是调用SRV.New_Thread()
:
threading.Thread(target=SRV.New_Thread).start()
如果您解决了这个问题,服务器现在将开始在后台收听。但是你会发现,即使在服务器启动之前,客户端甚至可以在点击任何内容之前立即打印出“连接被拒绝”。然后,单击该按钮不会再次尝试。
问题在于:
but1 = tkinter.Button(top, text ="send", command = self.buttonClick())
在初始化期间,您调用 self.buttonClick()
,然后将该方法调用的返回值指定为按钮的command
。你想要做的是使方法本身成为按钮的命令。像这样:
but1 = tkinter.Button(top, text ="send", command = self.buttonClick)
接下来,当您单击该按钮时,仍然会“拒绝连接”。为什么服务器拒绝您的连接?
不是。这是你自己的错误处理误导你。无论如何,您都会为任何例外打印该消息。如果你改变它来做到这一点:
except Exception as e:
print('failed to connect:', e)
您会看到实际问题是:
failed to connect: local variable 'port' referenced before assignment
如果您在代码中看得更远,如果self.p == ''
,则永远不会设置port
;相反,您设置了self.p
。
如果你修复了所有这些,当你点击按钮时,它就会连接。
还有一些其他问题。仅举一个例子:您的服务器代码只接受一个连接,从中读取一次,然后退出。因此,如果您单击按钮两次,客户端将尝试第二次连接,并等待永远,因为没有人接受连接。 (如果你真的关闭了套接字,你至少会得到一个错误,而不是永远阻塞。)如果你想让按钮多次工作,你需要在{{1}周围放置一个while True:
循环代码,所以它会在每个完成后等待新的连接。