我有一个简单的套接字程序。首次运行时有效。之后,当我断开客户端连接并添加新客户端时,它将接收空白数据。
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())无效。