我无法弄清楚我的代码有什么问题。我使用 pycharm 调试器发现我的服务器代码有问题 - 使用命令 clients_name.append(name)
。
我的服务器代码:
服务器.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()
我的客户代码:
客户端.py
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"
}
}
此代码是概念验证,不应按原样使用。
关于Python Socket - 网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39880806/