为什么我的管道破裂(python套接字)

2024-05-16 19:08:07 发布

您现在位置:Python中文网/ 问答频道 /正文

#!/usr/bin/python

from tkinter import *
from tkinter.ttk import *
from socket import *
import select

class window(Frame):

    def __init__(self, parent, name, networker):
        self.networker = networker
        self.name=name
        self.count=0
        self.scrollx=900
        self.scrolly=0

        self.messageStr=""
        Frame.__init__(self, parent)
        self.parent = parent

        self.parent.title("Chat")
        self.style = Style()
        self.style.theme_use("default")

        self.pack(fill=BOTH, expand="yes")

        self.lfone = Frame(self)

        self.messageCanvas = Canvas(self.lfone, relief=RAISED, height=0, width=0, scrollregion=(0,0,self.scrollx,self.scrolly))


        self.myentry = Entry(self)
        self.sendbutton = Button(self, text="Send", command=self.sendbuttoncommand)
        self.scrollbar = Scrollbar(self.lfone)


        self.lfone.pack(fill=BOTH, expand="yes")
        self.myentry.pack(side=LEFT, fill=BOTH, expand="yes", padx=5)

        self.messageCanvas.pack(side=LEFT, fill=BOTH, expand="yes", padx=5, pady=5)
        self.sendbutton.pack(side=RIGHT, padx=5)
        self.scrollbar.pack(side=RIGHT, fill=Y, pady=5)


        self.messageCanvas.configure(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.messageCanvas.yview)

        self.doListen()

    def sendbuttoncommand(self):
        self.count=self.count+20
        self.scrolly=self.scrolly+20
        str = (self.name + ": " + self.myentry.get())
        b = bytearray(str, "utf-8")
        self.messageCanvas.create_text(5, self.count, anchor=SW, text=(self.name + ": " + self.myentry.get()))
        self.messageCanvas.config(scrollregion=(0,0,self.scrollx, self.scrolly))
        self.networker.myhost.send(b)

    def post(self, str):
        self.count=self.count + 20
        self.scrolly=self.scrolly+20
        self.messageCanvas.create_text(5, self.count, anchor=SW, text=str)
        self.messageCanvas.config(scrollregion=(0,0,self.scrollx, self.scrolly))

    def doListen(self):
        str = self.networker.listen()
        if str != "":
            self.post(str)
        self.after(128, self.doListen)

class splash(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent=parent
        parent.title("INIT")
        self.splashed=False
        self.initgui()

    def initgui(self):
        self.style = Style()
        self.style.theme_use("default")
        self.pack(fill=BOTH, expand=YES)

        self.label = Label(self, text="Choose a name")
        self.entry = Entry(self)
        self.button = Button(self, text="Submit", command=lambda: self.doSplash())
        self.ipentry = Entry(self)
        self.iplabel = Label(self, text="IP addr to connect to:")

        self.label.pack(side=TOP, pady=5)
        self.entry.pack(fill=X, expand=YES, padx=5)
        self.iplabel.pack()
        self.ipentry.pack(fill=X, padx=5)
        self.button.pack(side=BOTTOM, pady=5)

    def doSplash(self):
        self.name=self.entry.get()
        #TODO: exception handling for ip addr
        self.addr=self.ipentry.get()
        self.splashed=True
        self.parent.destroy()

class networker():

    def __init__(self):
        self.myhost = socket(AF_INET, SOCK_STREAM)
        self.myclient = socket(AF_INET, SOCK_STREAM)
        self.host=gethostname()
        self.port=2007
        self.myhost.bind((self.host,self.port))
        self.myhost.listen(5)
        self.clientConnected=False
        self.myhost.setblocking(0)

    def connectToHost(self, hostname):
        self.myclient.connect((hostname,self.port))

    def getClient(self):
        self.client, self.addr = self.myhost.accept()
        print("Got a connection from %s" % str(self.addr))
        self.clientConnected=True

    def listen(self):
        ready = select.select([self.myclient], [], [], 1)
        if ready == 0:
            str = self.myclient.recv(1024)
            return str
        return ""



def main():

    myN = networker()

    splashRoot = Tk()
    splashApp=splash(splashRoot)
    splashRoot.mainloop()

    myN.connectToHost(splashApp.addr)
    myN.getClient()

    if splashApp.splashed:
        root = Tk()
        root.geometry("900x600+300+300")
        app=window(root, splashApp.name, myN)
        root.mainloop()

if __name__ == '__main__':
    main()

所以这应该是一个简单的聊天程序。对不起,所有的代码,但我担心它不会有意义,如果我削减了。你知道吗

想法: networker对象连接到输入的IP地址(在我的测试用例中是我自己的addr)并报告其成功。 窗口接受networker对象并在doListen()中调用其listen()方法。 doListen()使用after来多任务监听和维护gui。sendbuttoncommand()应该将条目中的消息发布到客户端和发送者的屏幕上,但它是错误的来源。你知道吗

大多数情况下,它工作,并声称连接成功。但是,当我尝试使用window.sendbuttoncommand命令(),我收到一个断管错误。一般来说,我对python和网络编程都是新手,不知道是哪个因素导致了这种情况。我的一些想法:

  1. 将networker对象传递到窗口对象可能会中断连接,因为它不像我假设的那样简单地传递引用。

  2. 在中使用after窗口.dolisten()可能会导致服务器只侦听短时间段,并且在该时间段内未捕获数据。

  3. 连接到我自己的设备可能会把事情搞砸。

任何建议/帮助/见解都将不胜感激。你知道吗


Tags: textnameselfdefcountfillsidepack
1条回答
网友
1楼 · 发布于 2024-05-16 19:08:07

这个问题的答案不是做我想做的事情,而是使用类似twisted的东西。不需要重新发明轮子

相关问题 更多 >