Skip to content Skip to sidebar Skip to footer

Python Tcp Server Accepting Connections And Broadcasting Commands

I've been working on a game using a number of Raspberry Pis, Python, and some buttons/switches. My game requires a central server that issues commands to multiple clients. I'm not

Solution 1:

Finally got it working! Much thanks to @Arman for pointing me in the right direction with the threading. I finally feel like I understand how everything is working!

Here is my complete Server & Client code. Hopefully this helps someone else with a master > client setup. The _broadcast() function is working as you will see it just broadcasts a static msg at the moment but that should be an easy update.

If anyone has any advice on code cleanup, python best practices using this code as the sample I would love to hear and learn more. Thanks again SE!

##Clientimport socket
import sys
import json

#vars
connected = False#connect to server
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('10.0.0.158',8888))
connected = Truewhile connected == True:
    #wait for server commands to do things, now we will just display things
    data = client_socket.recv(1024)     
    cmd = json.loads(data) #we now only expect json    if(cmd['type'] == 'bet'):
        bet = cmd['value']
        print('betting is: '+bet)
    elif (cmd['type'] == 'result'):        
        print('winner is: '+str(cmd['winner']))
        print('payout is: '+str(cmd['payout']))


##Serverimport socket, time, sys
import threading
import pprint

TCP_IP = ''
TCP_PORT = 8888
BUFFER_SIZE = 1024

clientCount = 0classserver():

    def__init__(self):
        self.CLIENTS = []        


    defstartServer(self):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.bind((TCP_IP,TCP_PORT))
            s.listen(10)
            while1:
                client_socket, addr = s.accept()
                print ('Connected with ' + addr[0] + ':' + str(addr[1]))
                global clientCount
                clientCount = clientCount+1print (clientCount)
                # register client
                self.CLIENTS.append(client_socket)
                threading.Thread(target=self.playerHandler, args=(client_socket,)).start()
            s.close()
        except socket.error as msg:
            print ('Could Not Start Server Thread. Error Code : ') #+ str(msg[0]) + ' Message ' + msg[1]
            sys.exit()


   #client handler :one of these loops is running for each thread/player   defplayerHandler(self, client_socket):
        #send welcome msg to new client
        client_socket.send(bytes('{"type": "bet","value": "1"}', 'UTF-8'))
        while1:
            data = client_socket.recv(BUFFER_SIZE)
            ifnot data: 
                break#print ('Data : ' + repr(data) + "\n")#data = data.decode("UTF-8")# broadcastfor client in self.CLIENTS.values():
                client.send(data)

         # the connection is closed: unregister
        self.CLIENTS.remove(client_socket)
        #client_socket.close() #do we close the socket when the program ends? or for ea client thead?defbroadcast(self, message):

        for c in self.CLIENTS:
            c.send(message.encode("utf-8"))

    def_broadcast(self):        
        for sock in self.CLIENTS:           
            try :
                self._send(sock)
            except socket.error:                
                sock.close()  # closing the socket connection
                self.CLIENTS.remove(sock)  # removing the socket from the active connections listdef_send(self, sock):        
        # Packs the message with 4 leading bytes representing the message length#msg = struct.pack('>I', len(msg)) + msg# Sends the packed message
        sock.send(bytes('{"type": "bet","value": "1"}', 'UTF-8'))


if __name__ == '__main__':
    s = server() #create new server listening for connections
    threading.Thread(target=s.startServer).start()

    while1:       
        s._broadcast()
        pprint.pprint(s.CLIENTS)
        print(len(s.CLIENTS)) #print out the number of connected clients every 5s
        time.sleep(5) 

Solution 2:

I have a multithread approach here :

s.listen(10)
    while1:
        client_socket, addr = s.accept()
        print ('Connected with ' + addr[0] + ':' + str(addr[1]))
        threading.Thread(target=self.handler, args=(client_socket, addr)).start()        


defhandler(self, client_socket, addr):
    while1:
        data = client_socket.recv(BUFF)
        print ('Data : ' + repr(data) + "\n")
        data = data.decode("UTF-8")

I strongly recommend you two write a class for Server and Client, for each client create a Client object and connect it to Server, and store each connected Client (its socket and a name for example) to a dictionary as you did, then you want to broadcast a message you can go through all connected Clients in Server and broadcast message you want like this:

defbroadcast(self, client_socket, message):
        for c inself.clients:
            c.send(message.encode("utf-8"))

Update

Because you have a thread that runs main you need another thread for running server , I suggest you write a start method for server and call it in a thread :

defstart(self):
    # all server starts stuff comes here as define socket 
    self.s.listen(10)
    while1:
        client_socket, addr = self.s.accept()
        print ('Connected with ' + addr[0] + ':' + str(addr[1]))
        threading.Thread(target=self.handler, args=(client_socket, addr)).start()

now in main section or main file after create server object run the start thread :

a = server()
threading.Thread(target=a.start).start()

Post a Comment for "Python Tcp Server Accepting Connections And Broadcasting Commands"