我使用套接字,select和tkinter创建了一个聊天系统,但是如果客户端重新启动,则在重新启动服务器之前它将无法再次连接。
这是客户端代码:
from tkinter import *
import tkinter.scrolledtext as tkst
import socket
import threading
import time
class myChatProgram(threading.Thread):
def __init__(self):
self.root = Tk()
self.myFrame = Frame(master = self.root)
self.myFrame.pack(fill='both', expand='yes')
self.chatArea = tkst.ScrolledText(
master = self.myFrame,
wrap = WORD,
width = 50,
height = 20
)
self.chatArea.configure(state='disabled')
self.chatArea.pack(padx=10, pady=10, fill=BOTH, expand=True)
self.bottomFrame = Frame(master = self.root)
self.bottomFrame.pack(fill='x', expand='yes' , side = "bottom")
self.entryBox = Entry(self.bottomFrame)
self.entryBox.pack(padx=10, pady=10,fill='x', expand='yes' , side = "left")
self.entryButton = Button(self.bottomFrame, text = "Send", command = self.sendText ,padx=10)
self.entryButton.pack(side = "right")
self.host = '192.168.1.150'
self.port = 50003
threading.Thread.__init__(self)
self.start()
self.root.mainloop()
def addText(self,message):
if message != "":
self.chatArea.configure(state='normal')
self.chatArea.insert(END, str(message) + "\n")
self.chatArea.configure(state='disabled')
def sendText(self):
message = bytes(self.entryBox.get(),"utf-8")
self.addText(self.entryBox.get())
if message:
self.mySocket.send(message)
self.entryBox.delete(0, END)
def run(self):
self.mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.mySocket.connect((self.host,self.port))
time.sleep(1)
while True:
self.addText(str(self.mySocket.recv(4096).decode("utf-8")))
myClass = myChatProgram()
服务器代码是:
import socket
import select
import threading
class server(threading.Thread):
def __init__(self):
host = '192.168.1.150'
port = 50003
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((host,port))
print("Your ip is {0} ".format(socket.gethostbyname(socket.gethostname())))
self.server.listen(5)
self.sockets = []
self.sockets.append(self.server)
def main(self):
while True:
inputList , outputList , errorList = select.select(self.sockets, [], self.sockets)
for mySocket in inputList:
if mySocket == self.server:
newClient , addr = self.server.accept()
print(addr , " Connected")
self.sockets.append(newClient)
else:
try:
data = mySocket.recv(4096)
if data:
self.broadcast(mySocket,data)
else:
print("Connection sent 0 bytes.")
mySocket.close()
self.sockets.remove(mySocket)
except socket.error , e:
print("Client disconnected while sending message.")
mySocket.close()
self.sockets.remove(mySocket)
continue
for mySocket in errorList:
print("Select flagged client as crashed.")
mySocket.close()
self.sockets.remove(mySocket)
continue
def broadcast(self,mySocket,message):
print("sending {0}".format(message))
for client in self.sockets:
if client != mySocket and socket != self.server:
try:
client.send(bytes(message,"utf-8"))
except:
client.close()
self.sockets.remove(client)
continue
myClass = server()
myClass.main()
错误是:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python33\lib\threading.py", line 901, in _bootstrap_inner
self.run()
File "F:\Sockets\chatClient.py", line 49, in run
self.mySocket.connect((self.host,self.port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
然而,除非客户端重新启动,否则它会正常工作,然后崩溃。有什么想法是错的吗?
答案 0 :(得分:0)
我猜你必须设置SO_REUSEADDR:
socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)