Ich habe einen Server und einen Client und sie können miteinander verbinden und ich kann vom Client an den Server senden, aber nicht umgekehrt. Das Programm schlägt fehl, wenn ich versuche, Daten an den Client zurückzusenden.Kann nicht von Server-Socket zu Client-Socket mit Python senden
client.py
from tkinter import *
import socket
import threading
tLock = threading.Lock()
shutdown = False
host = '::1';
port = 5000;
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
class Application(Frame):
def __init__(self, master=None):
#Create master frame
Frame.__init__(self,master)
self.grid()
self.master.title("Test 1")
self.conn=False #State of connection to server
#Configure main frame
for r in range (4):
self.master.rowconfigure(r, weight=1)
for c in range (2):
self.master.columnconfigure(c)
#Create sub frames
TopFrame=Frame(master)
TopFrame.grid(row=0, column=0, rowspan=3)
BottomFrame=Frame(master, bg="green")
BottomFrame.grid(row=4, column=0, rowspan=3)
SideFrame=Frame(master, bg="red")
SideFrame.grid(column=1, row=0, rowspan=4)
#Create Chat log
self.chatlog=Text(TopFrame)
self.chatlog.pack(padx=5, pady=5)
#messenger and send button
self.e1=Entry(BottomFrame, width=92)
self.e1.pack(side=LEFT, pady=5, padx=5)
sendButton=Button(BottomFrame, text="Send", command=self.sendmessage, height = 1, width = 10)
sendButton.pack(side=LEFT)
#Create connect disconnect buttons
b1=Button(SideFrame, text="Connect", command=self.connect)
b1.grid(row=0, column=0, padx=5, pady=5)
b2=Button(SideFrame, text="Disconnect", command=self.disconnect)
b2.grid(row=1, column=0, padx=5, pady=5)
def connect(self): #Connect to server
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("===ATTEMPTING TO CONNECT TO SERVER\n"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
s.connect((host,port))
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, (s))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("\n\n PLEASE ENTER A USER NAME AND SEND"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
self.conn=True
print("Connected") #Connection successful
# M- Adding threading for receiving messages
rT = threading.Thread(target=self.receving, args=("RecvThread",s))
rT.start()
# When attempting to connect a second time, produces OS error: an operation was attempted on something that is not a socket
def disconnect(self):
if self.conn: #Tests to see if client is connected
s.close()
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("===DISCONNECTED FROM SERVER.\n"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
self.conn=False
else: #Prevents attempting to disconnect when already disconnected
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("===YOU AREN'T CURRENTLY CONNECTED.\n"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
def sendmessage(self):
if self.conn: #Prevents sending if not connected
self.msg=self.e1.get()
if self.msg == "": #Empty message catcher
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("===YOU CANNOT SEND AN EMPTY MESSAGE.\n"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
else:
self.send_data(self.msg) #Sends message to the server
self.e1.delete(0, END)
else:
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("===YOU ARE NOT CONNECTED TO A SERVER. YOU CANNOT SEND A MESSAGE.\n"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
# M- Method to handle receiving from the server
# adds the data to the chat log.
def receving(self, name, sock):
while not shutdown:
try:
tLock.acquire()
while True:
data, addr = sock.recvfrom(1024)
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, (data + '\n'))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
except:
pass
finally:
tLock.release()
def send_data(self, message):
try:
s.send(message.encode('UTF-8'))
except:
self.chatlog['state'] = NORMAL
self.chatlog.insert(END, ("===THE PREVIOUS MESSAGE DIDN'T SEND. THIS IS POSSIBLY DUE TO A SERVER ERROR.\n"))
self.chatlog['state'] = DISABLED
self.chatlog.yview(END)
root = Tk()
app = Application(root)
app.mainloop()
Server.py
import socket
import threading
import sys
hosts=["::1"]
port=5000
#dictionay to hold the socket as the key and the user name as the value
dic = {}
class Server:
def __init__ (self,hosts,port):
self.host=hosts
self.port=port
self.socketserver=socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
self.socketserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Socket has been created successfully")
for i in hosts:
try:
host=i
self.socketserver.bind((host,port))
print("Connection succeded to address",i)
print ("The server is now binded to the following IP address",host,"Port",port)
break
except socket.error:
print("Connection failed to address",i)
else:
sys.exit()
def Accept_connections(self):
while True:
self.socketserver.listen(10)
print("Socket is now awaiting connections")
server, clientaddress = self.socketserver.accept()
print("Connection enstablished with: " +str(clientaddress))
threading.Thread(target = self.message,args = (server,clientaddress),).start()
def message(self,server,clientaddress):
while True:
try:
data= server.recv(1024)
print("data ", data)
#check to see if it is a new socket that is not in the stored
#socket dictionary
if server not in dic.keys():
print("if statement")
#if it is a new socket
#add the socket and the user name
dic[server] = data
for key in dic:
#send the joined message to the users
print("failing")
key.send("\n\n" + data + " has joined the chat")
else:
#alias is a variable used to store the sockets username
alias = dic[server]
for key in dic:
#send the message to the sockets in the dictionary
key.send(alias + ": " +data)
except:
server.close()
#edit this bit !
print("Data transfer failed")
return False
Server(hosts,port).Accept_connections()
Das Programm scheitert an:
key.send("\n\n" + data + " has joined the chat")
Wenn ein Client eine Verbindung herstellt sie einen Benutzernamen eingeben, wie bekannt sein. Dies speichert es mit einem Socket in einem Wörterbuch. Der Fehler tritt auf, wenn die Sockets umgangen werden, um die anderen Clients zu informieren, denen sie beigetreten sind. Jede Hilfe wäre brillant. Dies funktionierte auf python27, hat aber jetzt aufgehört, als ich auf python34 aktualisiert habe.
Ist die Programmausgabe ein Stacktrace, wenn der Fehler auftritt? Wenn ja, bitte geben Sie es an. – snakecharmerb
Hi, Die einzige Ausgabe ist "Datentransfer fehlgeschlagen" – sadWal
Ändern Sie die 'except:' Zeile in server.py zu 'exception as ex:' und fügen Sie unmittelbar nach: 'print (ex)' eine Zeile hinzu. Was wird gedruckt? (Ihr 'except' versteckt die Details des Fehlers). – snakecharmerb