我无法弄清楚,这里的代码有什么问题。我使用pycharm调试器,发现服务器代码中有问题-使用命令clients_name.append(name)

我的服务器代码:

Server.py

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()


我的客户代码:

客户端

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


请不要介意GUI的图形,我主要是在寻找可运行的应用程序。

我的想法是要有一个客户端代码-单击“刷新”时,它将从服务器获取所有clients_name。当我单击“免费”时,它将把我在文本框中输入的名称发送到服务器。

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)


我希望代码的行为如下:


运行服务器和客户端(打开GUI)
用户点击刷新-它从服务器获取数据-clients_name。这应该打印在我在GUI上的列表框中
然后,用户在文本框中输入名称,然后按“我有空”按钮-这应该从文本框中获取名称并将其发送到服务器。
然后,服务器读取名称,将其添加到clients_name变量。然后将其发送回(正常情况下-这是一个while循环)。如步骤2中所述,此信息将显示在列表框中。

最佳答案

该程序启动一个TCP服务器,该服务器在一个单独的线程中处理每个连接。客户端连接到服务器,获取客户端列表并进行打印。客户端列表作为JSON传输。接收缓冲区设置为1024字节,因此长于此长度的客户端列表将不会被完全接收。

client_list.py

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()


服务器输出

$ python client_list.py
Starting server...


客户输出

$ python client_list.py -c -n name1
{
    "name1": {
        "address": "127.0.0.1",
        "port": 62210,
        "name": "name1"
    }
}


此代码是概念证明,不应原样使用。

07-27 19:52