Problems with sockets and threads

D

Dexter Deejay

When i try to run this code and to connect to server (server is written in java that part of code is ok) everything stalls. Thread that i created hereoccupies processor all the time and GUI freezes. It's supposed to be waiting for message from server. (asynchronous one) Is there something that i did wrong here, or is there better way to do this?


from tkinter import *
from threading import *
import time
import socket
import sys

comPort=0
msg=""
name=socket.gethostbyname(socket.gethostname())
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
testArea=0
thread=0

def threadFunc():
global sock
global textArea
data=""
while(data==""):
try:
data=str((sock.recvfrom(256)),"UTF-8")
except BlockingIOError:
print("failed")
time.sleep(1)
data=""
textArea.add((data+"\n"))

def sendMsg():
global sock
message=name+": "+msg.get()+"\n"
sock.send(bytes(message,"UTF-8"))

def aboutCommand():
messagebox.showinfo(title="About",message="This is first (serious) aplication in python.")

def helpCommand():
messagebox.showinfo(title="Help",message="BAZINGA!")

def Connect():
global sock
global thread
sock.connect((serverIPString.get(), 16000))
sock.send(bytes("#connect request#\n",'UTF-8'))
data=sock.recvfrom(256)
reply=str(data[0],"UTF-8")
answer=(reply.split("#",3))
if(answer[1]!="connected"):
messagebox.showinfo(title="Error",message="Connection failed!")
return
sock.close();
sock=None
comPort=int(answer[2]) #for new connection
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((serverIPString.get(), comPort))
sock.setblocking(0)
thread=Thread(target=threadFunc())
thread.start()

def Disconnect():
global sock
sock.send(bytes("#END#\n","UTF-8"))
sock.close()

def ExitApplication():
Disconnect()
mGui.destroy()
return

mGui=Tk()
msg=StringVar()
serverIPString=StringVar()
mGui.geometry("400x600+200+20")
mGui.title("Chat client v1.0")

labServer=Label(mGui,text="Server IP adress: ").pack()
entServer=Entry(mGui,textvariable=serverIPString).pack()
btnConnect=Button(mGui,text="Connect",fg="red",bg="blue",command=Connect).pack()
btnDisconnect=Button(mGui,text="Disconnect",fg="red",bg="blue",command=Disconnect).pack()
textArea=Text(mGui,bg="yellow").pack()
entMessage=Entry(mGui,textvariable=msg).pack()
btnSendMsg=Button(mGui,text="Send message",fg="white",bg="black",command=sendMsg).pack()

menuBar=Menu(mGui)

fileMenu=Menu(menuBar,tearoff=0)
fileMenu.add_command(label="Exit",command=ExitApplication)
menuBar.add_cascade(label="File",menu=fileMenu)

optionsMenu=Menu(menuBar,tearoff=0)
optionsMenu.add_command(label="Change chat name")
optionsMenu.add_command(label="Connect",command=Connect)
optionsMenu.add_command(label="Disconnect",command=Disconnect)
menuBar.add_cascade(label="Options",menu=optionsMenu)

helpMenu=Menu(menuBar,tearoff=0)
helpMenu.add_command(label="Help",command=helpCommand)
helpMenu.add_command(label="About",command=aboutCommand)
menuBar.add_cascade(label="Info",menu=helpMenu)
mGui.config(menu=menuBar)
mGui.mainloop()
 
W

Wayne Werner

When i try to run this code and to connect to server (server is written in java that part of code is ok) everything stalls. Thread that i created here occupies processor all the time and GUI freezes. It's supposed to be waiting for message from server. (asynchronous one) Is there something that i did wrong here, or is there better way to do this?


from tkinter import *
from threading import *

Everything I've read or used suggests to me that threading+tkinter is a
dangerous combination.

Mainly because tkinter already has an event loop, so when you start mixing
threads things tend to go sideways.

Instead what you'll want to do is put processing in the .after or
..after_idle callbacks - just make sure that whatever is doing is quick (or
can do a portion of the activity quickly).

HTH,
-W
 
D

Dexter Deejay

Yeah, that seems to be problem. Waiting for message is in theory infinite. But why doesn't this separate thread leave processor while it is sleeping?
 
W

Wayne Werner

Yeah, that seems to be problem. Waiting for message is in theory infinite. But why doesn't this separate thread leave processor while it is sleeping?

As far as I've been able to tell? Magic ;)

But I haven't really dug into it. If you're really doing some waiting
stuff you might want to look into some other type of message passing
mechanism, e.g. launch a subprocess to do ths listening and then writing
to a file and checking that from within Tkinter. I expect there are other
possibilities that more advanced people may be able to recommend and are
probably better. But that seems like it would work.

HTH,
-W
 
D

Dexter Deejay

Thanks for help. Do you have any reference to pint me out for that subprocess creation?
 
D

Dexter Deejay

Thanks for help. Do you have any reference to direct me for that subprocess creation?
 
D

Dexter Deejay

FOUND ERROR! :D In creatin method of thread i wrote treadFunc() and should have said threadFunc (as pointer). Now i have problem with Text component. How to append string at end of it?
 
P

Peter Otten

Dexter said:
When i try to run this code and to connect to server (server is written in
java that part of code is ok) everything stalls. Thread that i created
here occupies processor all the time and GUI freezes. It's supposed to be
waiting for message from server. (asynchronous one) Is there something
that i did wrong here, or is there better way to do this?

Fredrik Lundh has an example that shows how to update a Text widget from
another thread:

http://effbot.org/zone/tkinter-threads.htm
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top