Reputation:
The code I've been working on doesn't seem to permit a connection, or return errors, or do anything. I can't figure out what's wrong since no errors are thrown. Can anyone help me debug. The client is supposed to send text on button click and the server just receives and prints messages. As I said, the program runs, but doesn't print anything and doesn't do anything after to show errors or issues so I can't identify how to fix it. Any assistance would be appreciated.
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()
Upvotes: 0
Views: 1467
Reputation: 365597
You have three major problems here, as well as a slew of smaller ones.
First, as Daniel Roseman says, just calling a method New_Thread
doesn't magically make it threaded.
But that's easy to fix. Instead of calling SRV.New_Thread()
, you can just do this:
threading.Thread(target=SRV.New_Thread).start()
If you fix that, the server will now start listening in the background. But you'll see that the client prints out "connection refused" immediately, before you can even click anything, even before the server gets started. And then, clicking the button doesn't make it try again.
The problem is here:
but1 = tkinter.Button(top, text ="send", command = self.buttonClick())
During initialization, you're calling self.buttonClick()
, and then assigning the return value from that method call as the button's command
. What you want to do is make the method itself be the button's command. Like this:
but1 = tkinter.Button(top, text ="send", command = self.buttonClick)
Next, when you click the button, you still get "connection refused". Why is the server refusing your connection?
It's not. That's your own error handling misleading you. You print out that message for any exception, no matter what. If you change it to do this:
except Exception as e:
print('failed to connect:', e)
You'll see that the actual problem is:
failed to connect: local variable 'port' referenced before assignment
And if you look farther up in your code, if self.p == ''
, you never set port
; instead, you set self.p
.
And if you fix all of those, when you click the button, it will connect.
There are still some other problems. Picking just one example: your server code just accepts one connection, reads from it once, then exits. So, if you click the button twice, the client tries to connect a second time, and waits forever because nobody's accepting the connection. (If you'd actually closed the socket, you'd at least get an error instead of blocking forever.) If you want the button to work multiple times, you need to put a while True:
loop around the New_Thread
code, so it will wait for a new connection after each one finishes.
Upvotes: 3