0

I am trying to make a simple chat application using Python 3. I have seen this work in the past, where my client is able to connect to my server, and messages can be sent successfully. I want to move the app from a script working in the python idle shell to a GUI built with TKinter. Using entry and button widgets, a client can connect to the server for a fraction of a second, then is immediately disconnected. This only seems to happen because I am trying to use tkinter.

Error message is:

%$%$ has connected.
Exception in thread Thread-33:
Traceback (most recent call last):
  File "C:\Users\lmaor\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\Users\lmaor\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\lmaor\Desktop\Server 2.py", line 32, in handle_client
    name = client.recv(BUFSIZ).decode("utf8")
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

The client-side code is:

#Importing packages
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
from tkinter import *
from tkinter import messagebox

global client_socket
global HOST
global PORT

#These are here to stop the program breaking later on
HOST = 1
PORT = 1
BUFSIZ = 1024
client_socket = socket(AF_INET, SOCK_STREAM)

#This unsuccessfully connects to the server
def connect():
    HOST = etyHost.get()
    PORT = etyPort.get()


    if not PORT:
        PORT = 33000  # Default value.
    else:
        PORT = int(PORT)

    client_socket = socket(AF_INET, SOCK_STREAM)
    BUFSIZ = 1024
    ADDR = (HOST, PORT)

    client_socket.connect(ADDR)
    receive_thread = Thread(target=receive)
    receive_thread.start()


#Creates a function to receive messages at any time
def receive():
    while True:
        try:
            global client_socket
            msg = client_socket.recv(BUFSIZ).decode("utf8")
            msgChatlog.insert(END, msg)
        except OSError:
            break

#Creates a function to send messages
def send(event=None):  #Event is passed by binders
    msg = varMessage.get()
    varMessage.set("")  #Clears input field
    client_socket.send(bytes(msg, "utf8"))
    if msg == "{quit}":
        client_socket.close()
        top.quit()

#When closing window
def on_closing(event=None):
    varMessage.set("{quit}")
    send()

#Create tkinter window
jahchat = Tk()
jahchat.geometry("500x500")
jahchat.configure(background = "black")
jahchat.resizable(False, False)
jahchat.title("JahChat")

#
#Frame contains everything. useless
frmMessage = Frame()

#Var message is what goes into the chat
varMessage = StringVar()  # For the messages to be sent.
varMessage.set("Type your messages here.")

#Scrollbar for the chatlog
srlChatlog = Scrollbar(frmMessage)  # To navigate through past messages.

#

msgChatlog = Listbox(frmMessage, height=15, width=100, yscrollcommand=srlChatlog.set)
srlChatlog.pack(side=RIGHT, fill=Y)
msgChatlog.pack(side=LEFT, fill=BOTH)
msgChatlog.pack()

frmMessage.pack()

#

etyMessage= Entry(textvariable=varMessage)
etyMessage.bind("<Return>", send)
etyMessage.pack()

btnMessage = Button(text="Send", command=send)
btnMessage.pack()

#jahchat.protocol("WM_DELETE_WINDOW", on_closing)

#Entry box
etyHost = Entry(jahchat)
etyHost.pack()
etyHost.place(x = 0, y = 250)

#Entry box
etyPort = Entry(jahchat)
etyPort.pack()
etyPort.place(x = 0, y = 275)

#Button
btnConnect = Button(jahchat, text = "Connect", command = connect)
btnConnect.config(width = 20)
btnConnect.place(x = 0, y = 320)


#========================================================
#This is the code that sucessfully connects to the server

#HOST = input("host")
#PORT = input("port")

#if not PORT:
#    PORT = 33000  # Default value.
#else:
#    PORT = int(PORT)

#client_socket = socket(AF_INET, SOCK_STREAM)
#BUFSIZ = 1024
#ADDR = (HOST, PORT)
#print (ADDR)
#print (type(ADDR))
#client_socket.connect(ADDR)

#receive_thread = Thread(target=receive)
#receive_thread.start()

#===========================================================




jahchat.mainloop()  # Starts GUI execution.

The server code is:

#Importing packages
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread

#Sets up constant variables for later use
clients = {}
addresses = {}

HOST = '' #Client has to set this as their host to connect
PORT = 33000 #Client has to set this as their port to connect
BUFSIZ = 1024
ADDR = (HOST, PORT)
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)

#Creates a function that handles clients into the server
def accept_incoming_connections():
    while True:
        client, client_address = SERVER.accept()
        print ("%$%$ has connected." .format(client_address))
        client.send(bytes("Greetings from the cave!" + "Now type your name and press enter!", "utf8"))
        addresses[client] = client_address
        Thread(target=handle_client, args=(client,)).start()

#Takes client socket as argument.
def handle_client(client):

    name = client.recv(BUFSIZ).decode("utf8")
    welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name
    client.send(bytes(welcome, "utf8"))
    msg = "%s has joined the chat!" % name
    broadcast(bytes(msg, "utf8"))
    clients[client] = name
    while True:
        msg = client.recv(BUFSIZ)
        if msg != bytes("{quit}", "utf8"):
            broadcast(msg, name+": ")
        else:
            client.send(bytes("{quit}", "utf8"))
            client.close()
            del clients[client]
            broadcast(bytes("%s has left the chat." % name, "utf8"))
            break

#Broadcasts message to whole server
def broadcast(msg, prefix=""): #Prefix is for name identification.

    for sock in clients:
        sock.send(bytes(prefix, "utf8")+msg)

def checkIP():
    print (HOST, PORT, ADDR)

if __name__ == "__main__":
    SERVER.listen(5)  # Listens for 5 connections at max.
    print("Waiting for connection...")
    ACCEPT_THREAD = Thread(target=accept_incoming_connections)
    ACCEPT_THREAD.start() #Starts the infinite loop.
    ACCEPT_THREAD.join()
    SERVER.close()

All answers appreciated.

gamer117
  • 13
  • 1
  • This is not "refusing to connect" as the title suggests. In the body you even describe that the connect was successful and from the trace one can see that it fails during `recv` from client which implies that it has a successful connection from the client in the first place. – Steffen Ullrich Nov 15 '19 at 06:02
  • Change to `except OSError as e: ; print('OSError, break:{}'.format(e))` to see why the client `breaks`. – stovfl Nov 15 '19 at 10:00
  • OSError, break:[WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied – gamer117 Nov 17 '19 at 23:48
  • Is this the printed error message? Relevant [Sockets, Advanced Chat Box](https://stackoverflow.com/a/39619882/7414759) and [Why does server and client gets out of sync? (python sockets)](https://stackoverflow.com/a/55163994/7414759) – stovfl Nov 18 '19 at 08:50

0 Answers0