2016-03-29 2 views
0

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.

+0

Ist die Programmausgabe ein Stacktrace, wenn der Fehler auftritt? Wenn ja, bitte geben Sie es an. – snakecharmerb

+0

Hi, Die einzige Ausgabe ist "Datentransfer fehlgeschlagen" – sadWal

+0

Ä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

Antwort

1

Verwaltet, um den Fix zu finden. Als ich auf 3 upgrated, hörte das Senden auf zu arbeiten, da es versuchte, Zeichenfolgen zu senden. Python 3 benötigt Bytes gesendet werden.

key.send(data + b' joined') 

wurde die Lösung

Verwandte Themen