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()
-
4Calling a method "New_Thread" doesn't magically make it threaded.Daniel Roseman– Daniel Roseman2014年01月03日 19:44:50 +00:00Commented Jan 3, 2014 at 19:44
-
to add to that accept is blocking so it waits for a connection ... client code should be a separate script that you run after starting the server ...Joran Beasley– Joran Beasley2014年01月03日 19:47:41 +00:00Commented Jan 3, 2014 at 19:47
-
@JoranBeasley: That isn't a problem; if his server actually created a new thread, it could run concurrently with the client in the same script.abarnert– abarnert2014年01月03日 19:52:31 +00:00Commented Jan 3, 2014 at 19:52
-
yeah I know ... but since its not threaded it blocks until a connection is accepted ... but yeah I could take out the part about the client in a separate file ... that just may be easier for him for nowJoran Beasley– Joran Beasley2014年01月03日 19:54:25 +00:00Commented Jan 3, 2014 at 19:54
-
1why ? it wont go past the .accept() call ... which is before you create your client ... you need to either put the client stuff in its own script and run it seperately or you need to actually implement threading now ...Joran Beasley– Joran Beasley2014年01月03日 20:03:28 +00:00Commented Jan 3, 2014 at 20:03
1 Answer 1
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.