python – Make server socket on tkinter allow input from clients


The program works correctly, it creates a server for its user, the server opens without any problems. But when I use a client to access it, the following message appears on the server's client:

Traceback (most recent call last): File "C:\Users\JF Andrade\Desktop\ScriptsPython\Programa011(Cliente_Servidor).py", line 10, in sockobj.connect((serverHost, serverPort)) ConnectionRefusedError: [WinError 10061] No connections could be made because the target machine actively refused them.

Could someone explain why this error? Thanks in advance.**

server side

from tkinter import *
from socket import *
import time

 class AdminTools(object):
      def __init__(self, main):

            self.font = ("Verdana", "8", "bold")

            self.Frame1 = Frame(main)
            self.Frame1["bg"] = "LightBlue"

            self.LabDiv2 = Label(main,text = "-----------------------------------------------------------")
            self.LabDiv2["bg"] = "LightBlue"

            self.Lab1 = Label(main,text = "Bem-vindo ao Server Manager", fg = "Red", font = self.font)
            self.Lab1["bg"] = "LightBlue"

            self.LabDiv1 = Label(main,text = "-----------------------------------------------------------")
            self.LabDiv1["bg"] = "LightBlue"

            self.Lab2 = Label(main, text = "CRIAR NOVO SERVIDOR ", fg = "Green")
            self.Lab2["bg"] = "LightBlue"

            self.Lab3 = Label(main, text = "HOST:", fg = "Black")
            self.Lab3["bg"] = "LightBlue"

            self.Txt1 = Entry(main, bg = "LightGrey", fg = "Red")

            self.Del1 = Button(main, bg = "Red", text = "Del", command = self.ExcluirTexto, width = 6)

            self.Lab4 = Label(main, text = "PORTA:", fg = "Black")
            self.Lab4["bg"] = "LightBlue"

            self.Txt2 = Entry(main, fg = "Red", bg = "LightGrey")

            self.LabSpc1 = Label(main,text = "")
            self.LabSpc1["bg"] = "LightBlue"

            self.Bt1 = Button(self.Frame1, text = "CRIAR SERVER", fg = "Black", bg = "Green", command = self.CriarServer, width = 12)

            self.LabSpc1 = Label(self.Frame1, text = "", pady = 0)
            self.LabSpc1["bg"] = "LightBlue"

            self.Bt2 = Button(self.Frame1, text = "FECHAR SERVER", bg = "RED", width = 12, command = self.FecharServer)

    def ExcluirTexto(self):
                    self.Txt1.delete(0, END)

    def CriarServer(self):
                    Host = str(self.Txt1.get())
                    Port = int(self.Txt2.get())
                    sockobj = socket(AF_INET, SOCK_STREAM) 
                    sockobj.bind((Host, Port))
                    print("Servidor iniciado")
                    self.Lab3["text"] = "SERVIDOR INICIADO COM SUCESSO!"
                    self.Lab3["fg"] = "Blue"                                                               


  main.title("Server Manager v1.0")

  main["bg"] = "LightBlue"

  main = Tk()

  main.geometry ("300x300")


Client side

  from socket import *

   serverHost = 'localhost'
   serverPort = 45

   sockobj = socket(AF_INET, SOCK_STREAM)
   sockobj.connect((serverHost, serverPort))
   print("Conexão estabelecida")


The problem with this code is that although the function that creates a socket for the server is called, it doesn't do anything else: it creates a new server, connects it to the port, says it will listen for up to 5 connections and then "finishes" – at the end, all objects created inside it, which are referenced outside the scope of the function, are destroyed by Python (and if by chance Python didn't do this, you would have a socket in the system, occupying the port, but without having access to it. it from Python code).

In practice your sockets are destroyed fractions of a second after they are created – you need a call to the accept method which will stop your program execution (and freeze the tkinter interface), while waiting for a new connection.

So to make this work from the outside that do something, you don't just put a call to socketobj.accept at the end of the CriarServer method – ideally you should set a timeout for the socket, call accept – and, if there is an incoming connection, manage this in a series of functions that act as events to tkinter – and do not make any blocking calls to sockets (either accept or recv ) if a timeout. You can use Python lists and dictionaries to manage multiple connections to the server in the main thread – or use one thread per connection – but then you'll have to figure out how those threads work well in conjunction with tkinter.

It might work out there if it's a low-resource program: a personal chat, or an intranet test. If it's a server for a service that may need to scale to hundreds (or even several dozen) of clients, it's best not to try to use it in conjunction with tkinter – write the server using asyncio, and create a program in tkinter (or even a webpage, why not?) to be the interface that also connects as a client, but with special capabilities. That way you don't have to worry about sharing the resources of the process that is your server with all the graphics that tkinter has to manage.

Scroll to Top