#!/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)并报告其成功。 window接受一个networker对象并在doListen()中调用它的listen()方法。 doListen()使用after来执行多任务侦听和维护gui。 sendbuttoncommand()应该在条目中将消息发布到客户端和发送者的屏幕,但是是错误的来源。
大部分都有效,并声称连接成功。但是,当我尝试使用window.sendbuttoncommand()时,我收到一个损坏的管道错误。我对python和网络编程都很陌生,并且不知道十亿内容中的哪一个导致了这一点。我的一些想法:
将网络对象传递给窗口对象可能会破坏连接,因为它不是像我假设的那样简单地传递引用。
在window.dolisten()中使用after可能导致服务器只监听短暂的时间段,并且在该时间段内没有捕获数据。
连接到我自己的设备可能会搞砸了。
非常感谢任何建议/帮助/见解。
答案 0 :(得分:0)
这个问题的答案不是做我想做的事情而是使用像扭曲的东西。无需重新发明轮子