简体   繁体   English

无法使用python从服务器套接字发送到客户端套接字

[英]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 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 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. 这在python27上工作,但是当我更新到python34时现在已停止。

Managed to find the fix. 设法找到修复程序。 When I upgraded to 3 the sending stopped working as it was trying to send strings. 当我升级到3时,由于尝试发送字符串,发送停止工作。 Python 3 requires bytes to be sent. Python 3要求发送字节。

key.send(data + b' joined')

Was the solution 是解决方案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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