TCP chat server using pyFltk

Lesson 30: TCP chat server using pyFltk

Chat Server code:

#tcp chat server

import socket
from fltk import *

class tcpwin(Fl_Window):
    def __init__(self,x,y,w,h,label):
        Fl_Window.__init__(self,x,y,w,h,label)
        self.begin()
        self.conbut=Fl_Light_Button(10,30,170,40,"Accept Connection")
        self.conbut.callback(self.conbut_cb)
        self.end()
        self.callback(self.close)

        self.connD={} #dictionary of established connections

    def conbut_cb(self, wid):
        host = 'localhost'
        port= 4444
        self.s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #fd=3

        self.s.bind((host, port))
        self.s.listen()
        fdl=self.s.fileno() #listening fd
        Fl.add_fd(fdl, self.acceptConnection) #watch for new connections

    def acceptConnection(self, fdl): #runs when data comes to socket s
        conn, raddr = self.s.accept()
        fd=conn.fileno() #file descriptor for new established connection
        Fl.add_fd(fd, self.receive_data)
        self.connD[fd]=conn #add fd(key) and conn(value) to connD dict

    def close(self,wid):
        try: # in case no connection
            for fd,conn in self.connD.items():
                conn.close()
                Fl.remove_fd(fd)
        except:
            print('closing without a connection')
        finally:
            self.hide()

    def receive_data(self, fd):
        data= self.connD[fd].recv(1024)
        print(data)
        if data==b'':
            self.connD[fd].close()
            Fl.remove_fd(fd)
            self.connD.pop(fd)
        else:
            for conn in self.connD.values():
                conn.sendall(data)

a=tcpwin(55,55,200,200,"TCP Server")
a.show()
Fl.run()

Client code: exactly the same as last lesson

#tcp client

import socket
from fltk import *

class tcpwin(Fl_Window):
    def __init__(self,x,y,w,h,label):
        Fl_Window.__init__(self,x,y,w,h,label)
        self.begin()
        self.conbut=Fl_Light_Button(40,30,270,40,"Connect")
        self.inp=Fl_Input(40,80,270,40,"Send:")
        self.brow=Fl_Multi_Browser(40,130,270,140)
        self.end()
        self.callback(self.close)

        self.conbut.callback(self.conbut_cb)
        self.inp.callback(self.send_cb)
        self.inp.when(FL_WHEN_ENTER_KEY)

    def conbut_cb(self, wid):
        host = 'localhost'
        port= 4444
        self.s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #fd=3

        self.s.connect((host,port))
        self.fd=self.s.fileno() #3

        Fl.add_fd(self.fd, self.receive_data)

    def close(self,wid):
        try:
            self.s.close()
        except:
            print('closing without a connection')
        finally:
            self.hide()

    def send_cb(self, widget):
        self.s.sendall(self.inp.value().encode())


    def receive_data(self, fd):
        data=self.s.recv(1024)
        print(data)
        if data==b'':
            self.s.close()
            Fl.remove_fd(self.fd)
        else:
            self.brow.add(data.decode())

a=tcpwin(55,55,333,333,"TCP Client")
a.show()
Fl.run()