Python Socket - Networking
<p>I am unable to figure out, whats wrong with my code here. I used pycharm debugger and found out that there is something wrong in my server code - with the command <code>clients_name.append(name)</code>.</p>

<p>My server Code: </p>

<h1>Server.py</h1>

<pre><code>import socket
import time
import numpy as np
import array

host = '127.0.0.1'
port = 5000

clients_name = ['NONE']
clients_addr = []
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Creating Socket OBJECT
s.bind((host, port))
s.setblocking(0)

quitting = False

print "Server Started"

while not quitting:
    try:
        data, addr = s.recvfrom(1024)
        print data

        for client in clients_addr:
            print "hello"
            s.sendto(clients_name, client)

        if int(data[0]) == 1:
            name = str(data[1])
            print name, type(name)
            if name not in clients_name:
                clients_name.append(name)

            print clients_name

            if addr not in clients_addr:

                clients_addr.append(addr)

            print data[1]
            print time.ctime(time.time()) + str(addr) + ": :" + str(data[1])


        elif int(data[0]) ==0:
            name = str(data[1])
            clients_name.remove(name)
            clients_addr.remove(addr)
    except:
        pass
s.close()
</code></pre>

<p>My Client Code: </p>

<h1>Client.py</h1>

<pre><code>import socket, threading, time, wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
from Communication import ReceiveData, SendData
import numpy as np

class windowClass(wx.Frame):

    def __init__(self, parent, title):
        global appSize_x
        global appSize_y

        appSize_x = 1100
        appSize_y = 800

        super(windowClass, self).__init__(parent, title = title, style = wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.CLOSE_BOX |wx.CAPTION, size = (appSize_x, appSize_y))

        self.basicGUI()
        self.Centre()
        self.Show()

    def basicGUI(self):
        # Font for all the text in the panel
        font = wx.Font(12, wx.ROMAN, wx.NORMAL, wx.BOLD)
        font2 = wx.Font(36, wx.MODERN, wx.ITALIC, wx.LIGHT)

        # Main Panel
        panel = wx.Panel(self)
        panel.SetBackgroundColour('white')

        self.title = wx.StaticText(panel, -1, "Work Transfer Application", pos=(150, 20))
        self.title.SetFont(font2)
        self.title.SetForegroundColour("RED")

        self.name_text_ctrl = wx.TextCtrl(panel, -1, size=(150, 40), pos=(100, 200))
        self.name_text_ctrl.SetFont(font)

        self.refresh = wx.Button(panel, -1, 'REFRESH', size = (225,30), pos = (100, 300))
        self.refresh.SetFont(font)
        self.refresh.SetBackgroundColour('YELLOW')
        self.refresh.Bind(wx.EVT_BUTTON, self.OnRefresh)

        self.free_button = wx.Button(panel, -1, 'I AM FREE', size = (225,30), pos = (100, 400))
        self.free_button.SetFont(font)
        self.free_button.SetBackgroundColour('GREEN')
        self.free_button.Bind(wx.EVT_BUTTON, self.OnFree)

        self.got_work_button = wx.Button(panel, -1, ' GOT WORK', size = (225, 30), pos = (100, 600))
        self.got_work_button.SetFont(font)
        self.got_work_button.SetBackgroundColour('RED')
        self.got_work_button.Bind(wx.EVT_BUTTON, self.OnGotWork)
        self.got_work_button.Disable()

        self.listbox = wx.ListBox(panel, -1, size=(300, 250), pos=(500, 200))
        self.listbox.SetFont(font)


    def OnRefresh(self, event):

        self.host = '127.0.0.1'
        self.port = 0
        self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.s.bind((self.host, self.port))
        self.s.setblocking(0)
        self.rT = threading.Thread(target=ReceiveData, name = "Receive Thread", args=(self.s,))
        self.rT.daemon = True

        self.rT.start()
        pub.subscribe(self.ReadEvent, "READ EVENT")


    def ReadEvent(self,arg1):
        self.people_list = arg1 # This goes to list box
        list_len = len(self.people_list)
        for i in range(list_len):
            self.listbox.Append(self.people_list[i])

    def OnFree(self, event):
        self.server = ('127.0.0.1', 5000) # This you UPDATE ONCE YOUR IP IS FIXED
        self.flag = np.array([ '1', str(self.name_text_ctrl.GetValue())])
        self.rS1 = threading.Thread(target = SendData, name = "Send Thread", args = (self.s,self.server, self.flag))
        self.rS1.start()
        self.got_work_button.Enable()
        self.rS1.join()
        print "Hello"

    def OnGotWork(self, event):

        self.flag = np.array([ '0', str(self.name_text_ctrl.GetValue())])
        self.rS2 = threading.Thread(target=SendData, name="Send Thread", args=(self.s, self.server, self.flag))
        self.rS2.start()
        self.rS2.join()
        self.s.close()
        self.Close(True)

def  main():
    app = wx.App()
    windowClass(None, title = 'Wagner SprayTech V2.0')
    app.MainLoop()

if __name__ == '__main__':  # if we're running file directly and not importing it
    main()  # run the main function
</code></pre>

<p>Please dont mind the Graphics of the GUI, I am mainly looking for a functioning application. </p>

<p>My idea is to have a client code - when I click Refresh - it gets all the <code>clients_name</code> from the server. When I click Free, it sends the name I enter in the textbox to the server. </p>

<pre><code>import threading, wx
import socket, time
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
import numpy as np



shutdown = False

lock = threading.Lock()
def ReceiveData(sock):

    while not shutdown:
        try:
            lock.acquire()
            #while True:
            data, addr = sock.recvfrom(1024)
            wx.CallAfter(pub.sendMessage, "READ EVENT", arg1 = data)
            print str(data) + "hehehe" # Thisd data will be posted on a list box.
        except:
            pass
        finally:
            lock.release()
            time.sleep(1)


def SendData(s, serv, data_send):

    lock.acquire()
    s.sendto(data_send, serv)
    lock.release()
    time.sleep(0.2)
</code></pre>

<p>I would like the code to behave as following: </p>

<ol>
<li>Run the server and client (opens the GUI)</li>
<li>The user hits Refresh - it get data from the server - which is <code>clients_name</code>. This should be printed on the listbox, I have on the GUI</li>
<li>Then the user enters a name in the text Box and presses, button " I am free" - this should take the name from the textBox and send it to the server. </li>
<li>The server then reads the name, adds to <code>clients_name</code> variable. Then sends it back (regularly - as it is a while loop). This information as said in step 2 - will be displayed on listbox. </li>
</ol>

<p>This program starts a TCP server that handles each connection in a separate thread. The client connects to the server, gets the client list, and prints it. The client list is transferred as JSON. The receive buffers are set to 1024 bytes, so a client list longer than this will not be completely received.</p>

<p><strong>client_list.py</strong></p>

<pre><code>import argparse
import json
import socket
import threading

def handle_client(client_list, conn, address):
    name = conn.recv(1024)
    entry = dict(zip(['name', 'address', 'port'], [name, address[0], address[1]]))
    client_list[name] = entry
    conn.sendall(json.dumps(client_list))
    conn.shutdown(socket.SHUT_RDWR)
    conn.close()

def server(client_list):
    print "Starting server..."
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('127.0.0.1', 5000))
    s.listen(5)
    while True:
        (conn, address) = s.accept()
        t = threading.Thread(target=handle_client, args=(client_list, conn, address))
        t.daemon = True
        t.start()

def client(name):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 5000))
    s.send(name)
    data = s.recv(1024)
    result = json.loads(data)
    print json.dumps(result, indent=4)

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', dest='client', action='store_true')
    parser.add_argument('-n', dest='name', type=str, default='name')
    result = parser.parse_args()
    return result

def main():
    client_list = dict()
    args = parse_arguments()
    if args.client:
        client(args.name)
    else:
        try:
            server(client_list)
        except KeyboardInterrupt:
            print "Keyboard interrupt"

if __name__ == '__main__':
    main()
</code></pre>

<p><strong>Server Output</strong></p>

<pre><code>$ python client_list.py
Starting server...
</code></pre>

<p><strong>Client Output</strong></p>

<pre><code>$ python client_list.py -c -n name1
{
    "name1": {
        "address": "127.0.0.1", 
        "port": 62210, 
        "name": "name1"
    }
}
</code></pre>

<p>This code is a proof-of-concept and should not be used as-is.</p>

python multithreading sockets