wxpython服务器
我试图通过套接字将数据从C程序发送到python脚本,以便使用matplotlib执行数据的实时可视化。我还使用wxPython创建了一个GUI。 我使用了socket模块、SocketServer模块和twisted。每一次我都有不同的问题 使用套接字模块,我得到了不止一条消息的组合。我减小了recv函数的缓冲区大小,但是我只得到了一个包,之后就什么都没有了 然后我开始使用twisted。我仍在收集包裹,而不是一个接一个。此外,当在C文件中插入延迟时,我的python脚本崩溃了 然后我转到SocketServer,创建了一个线程来运行服务器。消息是我想要的,但是我不能再与GUI交互了 我所要做的就是向Python脚本发送一个包含4个值的字符串,剥离它并绘制它,拥有一个交互式UI,但我找不到服务器、matplotlib和wxPython协作的示例 这是我找到并正在使用的C代码:wxpython服务器,python,sockets,matplotlib,wxpython,real-time-data,Python,Sockets,Matplotlib,Wxpython,Real Time Data,我试图通过套接字将数据从C程序发送到python脚本,以便使用matplotlib执行数据的实时可视化。我还使用wxPython创建了一个GUI。 我使用了socket模块、SocketServer模块和twisted。每一次我都有不同的问题 使用套接字模块,我得到了不止一条消息的组合。我减小了recv函数的缓冲区大小,但是我只得到了一个包,之后就什么都没有了 然后我开始使用twisted。我仍在收集包裹,而不是一个接一个。此外,当在C文件中插入延迟时,我的python脚本崩溃了 然后我转到So
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#define PORT 9992
#define HOST "localhost"
#define DIRSIZE 8192
main(argc, argv)
int argc; char **argv;
{
char hostname[100];
char dir[DIRSIZE];
int sd;
struct sockaddr_in sin;
struct sockaddr_in pin;
struct hostent *hp;
char message[50];
int i = 0;
int count = 50;
strcpy(hostname,HOST);
if (argc>2)
{ strcpy(hostname,argv[2]); }
/* go find out about the desired host machine */
if ((hp = gethostbyname(hostname)) == 0) {
perror("gethostbyname");
exit(1);
}
/* fill in the socket structure with host information */
memset(&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
pin.sin_port = htons(PORT);
/* grab an Internet domain socket */
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/* connect to PORT on HOST */
if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) {
perror("connect");
exit(1);
}
/* send a message to the server PORT on machine HOST */
while (i < 100){
sprintf(message, "%d %d %d %d \n", count, count + 50, count + 100, count + 130);
if (send(sd, message, strlen(message), 0) == -1) {
perror("send");
exit(1);
}
count = count + 50;
i++;
sleep(1);
}
shutdown (sd, 2);
}
对不起,我是Python新手。提前谢谢。我不能说套接字通信的最佳方法是什么,它实际上取决于应用程序的需要、传输数据的类型和格式、容量等。但是我可以帮助您与GUI应用程序集成 在向GUI应用程序添加套接字服务之类的东西时,有几个关键原则需要注意。首先,为了保持UI对用户的响应,您不应该在UI事件处理程序或其他回调中执行任何可能会阻塞用户相当长时间的操作。其次,您不应该从UI线程以外的线程创建或操作任何GUI元素 因此,您运行SocketServer或从其他线程使用的任何东西的本能是好的。这使您可以将线程的全部注意力放在处理通信上,而不必处理更复杂的事情,如定期轮询、对UI事件处理的让步等。它可以阻止等待传入的数据
有几种方法可用于将传入数据从套接字传输到UI线程。可能最简单的方法是使用wxPython的wx.CallAfter函数。它允许您指定一些应该调用的可调用对象,以及要传递给它的参数,然后它将导致在UI线程上下文中不久之后发生该调用。这是一个非常复杂的问题,您是否可以将其分解为更小的,更容易理解/处理区块?我不明白你的意思。我认为我的服务器位于不同的线程上,因此gui不应受到影响。但确实如此。抱歉,我对Python不太熟悉。如果您认为这主要是线程/wx问题,那么请去掉所有matplotilb代码,以便更容易看到发生了什么。如果一个问题只包含与再现问题相关的代码,您将得到更多更好的答案。或者,我们不需要查看您的UI设计的所有细节,人们为了找到问题而需要转换的代码越少越好。帮助我们帮助你;谢谢,我为代码中对问题没有实际影响的部分添加了注释……是的,但问题是,尽管我在不同的线程中运行服务器,但我的GUI还是会阻塞。我无法与GUI交互,并且我的服务器一直在后台运行…服务器线程CPU受限吗?这可能会导致UI线程的周期性不足。如果您制作一个小的可运行的示例来演示问题,那么它将更容易提供帮助。如果您将其发布到wxPython用户列表中,那么您可能会得到很多帮助。
class ThreadedEchoRequestHandler(SocketServer.StreamRequestHandler):
def handle(self):
cur_thread = threading.currentThread()
line = self.rfile.readline()
while True:
line = self.rfile.readline()
if not line: break
print "%s wrote: %s" % (self.client_address[0], line.rstrip())
self.wfile.write(line)
return
class ThreadedEchoServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
########################################################################################
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(1024,768))
self.SetIcon(wx.Icon('sim.ico', wx.BITMAP_TYPE_ICO))
self.SetBackgroundColour('#ece9d8')
self.add_toolbar()
self.Centre()
#Flag variables
self.isLogging = False
self.threads = []
server = ThreadedEchoServer(('localhost',9997), ThreadedEchoRequestHandler)
t = threading.Thread(target=server.serve_forever)
t.start()
#Create data buffers
#Some GUI Design Code
#Create timer to read incoming data and scroll plot
#Create start/stop button
self.start_stop_button = wx.Button(self, label="Start", pos=(80,550), size=(150,150))
self.start_stop_button.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False))
self.start_stop_button.Bind(wx.EVT_BUTTON, self.onStartStopButton)
def add_toolbar(self):
# Toolbar code
def onStartStopButton(self, event):
if not self.isLogging:
self.isLogging = True
self.start_stop_button.SetLabel("Stop")
call(["/home/user/Misc/socketTest/socketTest"])
else:
self.isLogging = False
self.start_stop_button.SetLabel("Start")
def GetSample(self, msg):
### Manipulate Data from socket for matplotlib update
if __name__ == '__main__':
app =wx.App(False)
frame = MyFrame(None, 'Sim')
frame.Show(True)
app.MainLoop()