Server code:
#tcp 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(40,30,270,40,"Accept Connection")
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.bind((host, port))
self.s.listen()
fdl=self.s.fileno() #listening fd
Fl.add_fd(fdl, self.acceptConnections) #watch for connection requests
def acceptConnections(self, fdl): #runs when data comes to socket s
self.conn, raddr = self.s.accept() #fd=4 blocking
self.fd=self.conn.fileno() #4
Fl.add_fd(self.fd, self.receive_data)
#watch for data through established connection
def close(self,wid):
try: # in case no connection
self.conn.close()
except:
print('closing without a connection')
finally:
self.hide()
def send_cb(self, widget):
self.conn.sendall(self.inp.value().encode())
def receive_data(self, fd):
data=self.conn.recv(1024)
print(data)
if data==b'':
self.conn.close()
Fl.remove_fd(self.fd)
else:
self.brow.add(data.decode())
a=tcpwin(55,55,333,333,"TCP Server")
a.show()
Fl.run()
Client code:
#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()
Below is a better solution with only one file for client and server
import socket,sys
from fltk import *
#usage: python3 program.py server/client localhost 5555
# 3 args: (client/server) host port
# remember machine to machine, host = 0.0.0.0 for server
class mywin(Fl_Window):
def __init__(self,x,y,w,h,label):
Fl_Window.__init__(self,x,y,w,h,label)
self.begin()
self.inp=Fl_Input(30,80,270,40,"Type")
self.inp.align(FL_ALIGN_LEFT_TOP)
self.sbut=Fl_Return_Button(30,130,270,40,"Send")
self.brow=Fl_Multi_Browser(30,180,270,140)
self.end()
self.callback(self.close) #close window callback
self.conn=0
self.sbut.callback(self.send_cb)
self.host = sys.argv[2]
self.port=int(sys.argv[3])
self.s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
if sys.argv[1] == "server":
self.s.bind((self.host, self.port)) # server must bind and listen
self.s.listen()
Fl.add_fd(self.s.fileno(), self.acceptconn)
elif sys.argv[1]=='client':
try:
self.s.connect( (self.host,self.port) ) #client connects to server
Fl.add_fd(self.s.fileno(), self.recvdata)
except:
print("Server needs to start first")
self.s.close()
sys.exit(1)
def acceptconn(self, fd):
if self.conn == 0: #only allow one client to connect
self.conn, addr = self.s.accept()
Fl.add_fd(self.conn.fileno(), self.recvdata)
def send_cb(self, widget):
text = self.inp.value()
self.brow.add("@B222@r"+text) #background color 222, right justified
if sys.argv[1] == "server":
try:
self.conn.sendall(text.encode())
except:
print("Client has not yet connected, or has disconnected")
elif sys.argv[1]=="client":
try:
self.s.sendall(text.encode())
except:
print('Server may have disconnected')
self.s.close()
self.hide()
self.inp.value('')
def recvdata(self, fd):
if sys.argv[1] == "server":
data=self.conn.recv(1024) #server communicates through socket conn
#data is null byte b'' when socket is closed
if data == b'':
Fl.remove_fd(self.conn.fileno())
print('stopped watching socket conn')
return
elif sys.argv[1]== "client":
data=self.s.recv(1024) #client communicates through socket s
if not data: #same as if data == b''
Fl.remove_fd(self.s.fileno())
print('stopped watching socket s')
return
self.brow.add(data.decode())
def close(self, wid):
if sys.argv[1]== "server":
self.conn.close()
self.s.close() #close socket s for both client and server
self.hide()
a=mywin(55,55,333,333,"sockets "+sys.argv[1])
a.show()
Fl.run()