简体   繁体   中英

Cant send from server socket to client socket using python

I have a server and a client and they can connect to each other and I can send from the client to the server but not vice versa. The program fails when i'm trying to send back data to the client.

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()

The program fails at:

    key.send("\n\n" + data + " has joined the chat")

When a client connects they enter a user name to be known as. This stores it with a socket in a dictionary. The error occurs when looping round the sockets to inform the other clients they have joined. Any help would be brilliant. This was working on python27 but has now stopped when i updated to python34.

Managed to find the fix. When I upgraded to 3 the sending stopped working as it was trying to send strings. Python 3 requires bytes to be sent.

key.send(data + b' joined')

Was the solution

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM