Python套接字收到空白消息

时间:2019-05-13 19:05:57

标签: python sockets

我有一个简单的套接字程序。首次运行时有效。之后,当我断开客户端连接并添加新客户端时,它将接收空白数据。

handle_login()函数中正在发生问题。但是如果我错过了某些东西,我会提供完整的代码。

Server.py

import socket
import re
import datetime


def write_startup():
    # Write information to the log file 'server.log'
    new_file = open("server.log", 'a+')
    new_file.write("Server started {} \n".format(str(datetime.datetime.now())))
    new_file.close()

def write_connection():
    # Write information to the log file
    new_file = open("server.log", 'a+')
    new_file.write("Client connected at {} ".format(str(datetime.datetime.now())))
    new_file.write("\nConnection was successful! ")
    new_file.close()

def write_disconnection(start):
    # Write information to the log file
    new_file = open("server.log", 'a+')
    connection = datetime.datetime.now() - start
    new_file.write("\nClient was connected for {} \n".format(str(connection)))
    new_file.write("\n")
    new_file.close()

def write_data(data):
    # Write information to the log file
    new_file = open("server.log", 'a+')
    new_file.write("\nClient requested songs under the artist name {} ".format(data))
    new_file.close()

class ReadingFile:
    def __init__(self):
        # Create regex that will be used for reading the file 'songs.txt
        self.start_line = re.compile('\S')
        self.end_line = re.compile('\d')

    def read_file(self, f_name):
        all_songs_dictionary = {}
        new_file = open(f_name, 'r')
        i = 0
        # Adds 100 songs to the dictionary
        while i < 100:
            hold = new_file.readline()
            # Calls the check function
            test = self.check(hold)

            # Adds the song and artist/artists to the dictionary
            if test == 'full':
                song = hold[4:34].strip()
                author = hold[35:-6].strip()
                for x in author.split('/'):
                    for y in x.split(' featuring '):
                        all_songs_dictionary.setdefault(y, []).append(song)
                i += 1
            elif test == 'name':
                song = hold[4:-1].strip()
                author = new_file.readline()[:-6].strip()
                all_songs_dictionary.setdefault(author, []).append(song)
                i += 1
        new_file.close()
        return all_songs_dictionary

    def check(self, full_line):
        # Uses the regex created previously to check that a line is valid
        if self.start_line.match(full_line[:1]):
            if self.end_line.match(full_line[-4:]):
                # This is when a full line has all the information
                return 'full'
            # This is when 2 lines contain all the information
            return 'name'
        else:
            # This is when the line is not required
            return 'none'


class Server:

    connection = None
    def __init__(self, songs):
        self.logged_in = False
        # Initialise the socket and address
        self.server_socket = socket.socket(socket.AF_INET)
        server_address = ('localhost', 6666) ## change if necessary, if changed here you should also change in the client.py program.
        print('Starting up on %s port %s' % server_address)
        try:
            # Attempt to start the server
            self.server_socket.bind(server_address)
            write_startup()
            # Listen for a connection
            self.server_socket.listen(0)
        except socket.error:
            # Catch any errors, such as the port being in use
            print("The server failed to initialise as the socket is already in use!")
            exit()
        self.song_dictionary = songs


    def handle_login(self):
        while not self.logged_in:
            print("Sending make_login to client..")
            self.connection.sendall("make_login".encode())
            print("make_login sent..")
            data = self.connection.recv(100).decode()
            if data=="mysecpass":
                self.logged_in=True
                self.connection.sendall("logged_in".encode())





    def running(self):

        # Wait for a connection
        # The while loops means that the server will keep listening after a client disconnects, unless they send 'close'        
        while 1:
            print('Waiting for a connection')
            self.logged_in = False
            print("made loggedin = false and starting acepting")
            connection, client_address = self.server_socket.accept()
            print("Accepted a new connection")
            if self.connection==None: self.connection = connection
            connection.send("Successful connection!!...tada".encode())
            print("conn sucsfl msg sent to the client..")
            try:
                # Output that a client has connected
                print('connection from', client_address)
                write_connection()
                # Set the time that the client connected
                start_time = datetime.datetime.now()

                # Loop until the client disconnects from the server
                self.handle_login()
                while self.logged_in:
                    # Receive information from the client
                    data = connection.recv(1024).decode()
                    if (data != 'quit') and (data != 'close'):
                        print('received "%s" ' % data)
                        connection.send('Your request was successfully received!'.encode())
                        write_data(data)
                        # Check the dictionary for the requested artist name
                        # If it exists, get all their songs and return them to the user
                        if data in self.song_dictionary:
                            songs = ''
                            for i in range(len(self.song_dictionary.get(data))):
                                songs += self.song_dictionary.get(data)[i] + ', '
                            songs = songs[:-2]
                            print('sending data back to the client')
                            connection.send(songs.encode())
                            print("Sent", songs)
                        # If it doesn't exist return 'error' which tells the client that the artist does not exist
                        else:
                            print('sending data back to the client')
                            connection.send('error'.encode())
                    else:
                        # Exit the while loop
                        break
                # Write how long the client was connected for
                write_disconnection(start_time)
            except:
                # Catch any errors and safely close the connection with the client
                print("There was an error with the connection, and it was forcibly closed.")
                write_disconnection(start_time)
                connection.close()
                data = ''
            finally:
                if data == 'close':
                    print('Closing the connection and the server')
                    # Close the connection
                    connection.close()
                    # Exit the main While loop, so the server does not listen for a new client
                    break
                else:
                    print('Closing the connection')
                    # Close the connection
                    connection.close()
                    # The server continues to listen for a new client due to the While loop
                    print('-'*30)


read = ReadingFile()
dictionary = read.read_file("songs.txt")
running_server = Server(dictionary)
running_server.running()



Client.py

import socket
import datetime


def write_response(start, finish, artist, length):
    # This writes information to the log file 'client.log
    new_file = open("client.log", 'a+')
    new_file.write("Server took {} to complete the request for '{}' ".format(str(finish - start), artist))
    new_file.write("\nThe response length was {} bytes ".format(str(length)))
    new_file.write("\nThe response was received on {} \n".format(str(datetime.datetime.now())))
    new_file.write("\n\n")
    new_file.close()


class RunningConnection:

    def handle_login(self):
        print("Checking login..")
        while not self.logged_in:
            print("recieving data about your login info..")
            msg = self.sock.recv(10).decode()
            print("info recieved..",msg)
            if msg=="make_login":
                print("you are not logged in to the server..")
                sendmsg = input("Enter Auth Credential: ")
                self.sock.sendall(sendmsg.encode())
            elif msg=="logged_in":
                print("You are successfully logged in!")
                self.logged_in=True




    def __init__(self):
        self.logged_in = False
        # Initialise the socket and address
        self.sock = socket.socket(socket.AF_INET)
        server_address = ('localhost', 6666) #change port number if necessary. If changed here you should also change it in the server.py program.
        print('connecting to %s on port %s' % server_address)
        try:
            # Set a timeout for the connection to allow it to fail if another client is already connected
            self.sock.settimeout(10)
            # Attempt to connect to the server
            self.sock.connect(server_address)
            print("Waiting to connect to the server...")
            print(self.sock.recv(100).decode())
        except socket.timeout:
            # Catch a timeout error
            print("There was a timeout error, as another user is already connected to the server!")
            print("No other connections will be able to be made to the server whilst it is running.")
            exit()
        except socket.error:
            # Catch any other errors that may arise, such as the server not running
            print("There was an error connecting to the server as it is not available/running.")
            exit()

    def running(self):
        try:

            # Loop until the user inputs close or quit
            self.handle_login() 
            while self.logged_in:
                message = ''
                # Loop until the user inputs a message (No blank message)
                while message == '':
                    message = input("What artist would you like to search for? ") # Getting the name of an artists from a user

                    if message == '': # simple error checking
                        print("ERROR: You should not send an empty message!")

                # Send the message to the server
                self.sock.sendall(message.encode())
                # Set the time that the message was sent
                start_time = datetime.datetime.now()

                # If the user input 'quit' or 'close', exit the while loop and close the connection
                if message == 'quit' or message == 'close':
                    print("Disconnecting!")
                    break

                # Output what the user is sending to the terminal
                print('You are sending "%s" message to the server: ' % message)

                # Receive a response from the server
                data = self.sock.recv(39)
                print(data.decode())
                data = self.sock.recv(1024)

                # 'error' is returned if no songs are found, otherwise the songs are displayed on the terminal
                if data.decode() == 'error':
                    print("There are no songs under the author", message)
                else:
                    print("The songs made by ", message, "are:")
                    print(data.decode())

                # Set the finish time, and call the function to write to the log file
                finish_time = datetime.datetime.now()
                write_response(start_time, finish_time, message, len(data))
                print("\nType in 'quit' to disconnect, or 'close' to quit and shut down the server!\n")
        except socket.timeout:
            # Catch a timeout error
            print("There was a timeout error!")
            self.sock.sendall('quit'.encode())
            self.sock.close()
            exit()
        except socket.error:
            # Catch any other errors that may arise, such as the server not running
            print("There was an error with the connection!")
            exit()
        finally:
            # Close the connection
            self.sock.close()


connect_client = RunningConnection()
connect_client.running()

我第二次注意到,来自handle_login()的 self.connection.sendall(“ make_login” .encode())无效。

0 个答案:

没有答案