diff --git a/proj2017/cs.py b/proj2017/cs.py new file mode 100644 index 0000000..3c33881 --- /dev/null +++ b/proj2017/cs.py @@ -0,0 +1,376 @@ +################################################################################ +# CENTRAL SERVER # +################################################################################ + +import socket +import signal +import sys +import select +import os +import glob + +################################################################################ +# VARIAVEIS # +################################################################################ +WSlist = [] + +################################################################################ +# FUNCOES # +################################################################################ + +def signal_handler(signal, frame): + print("*** Central Server is shutting down! ***") + socketUSER.close() + socketUDP.close() + sys.exit(0) + +def findPTC(ptc, lst): + res = [] + for el1 in lst: + for el2 in el1[2]: + if (el2 == ptc): + res += [[el1[0], el1[1]]] + return res + +def onlySocketsFromList(lst): + res = [] + for el in lst: + res += [el[0]] + return res + +def divideFile(filename): + file = open(filename, 'r') + lst = [] + lines = file.readlines() + count = 0 + for line in lines: + newfile = open("./input_files/" + filename[14:19] + str('%03d'%count) + ".txt" , 'w') + newfile.write(line) + newfile.close() + lst += ["./input_files/" + filename[14:19] + str('%03d'%count) + '.txt'] + count += 1 + return lst + +def doStuffUser(sock, addr, ListWS): + """ + Le do socket que comunica com o Utilizador + """ + BUFFER_SIZE = 1024 + bytesReceived = 0 + + try: + data = sock.recv(BUFFER_SIZE).decode() + bytesReceived = len(data) + parsed = data.split(' ') + if(parsed[0] == "REQ"): + while(bytesReceived < eval(parsed[2])): + data += sock.recv(BUFFER_SIZE).decode() + parsed = data.split(' ') + bytesReceived = len(data) + + except socket.error: + print("Erro a receber socketUSER") + os._exit(0) + + socketWS = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + message = "" + + if(parsed[0] == "LST\n"): + + PTClist = [] + PTCstr = "" + if len(WSlist) > 0: + for el1 in WSlist: + for el2 in el1[2]: + if el2 not in PTClist: + PTClist += [el2] + PTCstr += str(len(PTClist)) + " " + for el in PTClist: + PTCstr += el + " " + else: + PTCstr = "EOF" + message = "FPT " + PTCstr + print("List request:", addr[0], addr[1]) + elif parsed[0] == "REQ": + if not os.path.exists('./input_files'): + os.makedirs('./input_files') + fileNumber = 10000 + fileName = "./input_files/" + str(fileNumber) + ".txt" + while (os.path.exists(fileName)): + fileNumber += 1 + fileName = "./input_files/" + str(fileNumber) + ".txt" + file = open(fileName, "w") + print(fileNumber) + + data = "" + for i in range(3, len(parsed)): + data += parsed[i] + " " + + data = data[:-2] + file.write(data) + file.close() + + aux = findPTC(parsed[1], WSlist) + + + #Cria o diretorio se nao existir + if not os.path.exists('./output_files'): + os.makedirs('./output_files') + + #Divide o ficheiro + files = divideFile(fileName) + + WSsockets = [] + res = [] + i = 0 + print(files) + + for el in files: + if i == len(aux): + i = 0 + newfile = open(el, 'r') + dataFile = newfile.read() + MESSAGE = "WRQ " + parsed[1] + " " + el + ' ' + str(len(dataFile)) + ' ' + dataFile + "\n" + socketWS = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + socketWS.connect((aux[i][0] , eval(aux[i][1]))) + try: + socketWS.send(MESSAGE.encode()) + except socket.error: + print("Erro a enviar para WS") + os._exit(0) + WSsockets += [(socketWS, el[14:])] + i+=1 + + length = len(WSsockets) + for i in range(0, len(WSsockets)): + r, w, e = select.select(onlySocketsFromList(WSsockets), [], []) + + filename = "ERROR.txt" + socketWS = r[0] + for el in WSsockets: + if el[0] == r[0]: + filename = el[1] + #Recebe a data processada + messageWS = socketWS.recv(BUFFER_SIZE).decode() + bytesReceived = len(messageWS) + parsedWS = messageWS.split(' ') + + while(bytesReceived < eval(parsedWS[2])): + messageWS += socketWS.recv(BUFFER_SIZE).decode() + bytesReceived = len(mesageWS) + + messageWS = messageWS[:-1] + parsedWS = messageWS.split(" ") + res += parsedWS[3:] + toOutput = "" + for word in parsedWS[3:]: + if word[-1] == "\n": + toOutput += word + else: + toOutput += word + " " + outputFile = open("./output_files/" + filename, 'w') + outputFile.write(toOutput) + outputFile.close() + + socketWS.close() + WSsockets.remove((socketWS, filename)) + del(r[0]) + + + if parsed[1] == "FLW": + count = len(res[0]) + word = res[0] + for el in res: + if len(el) > count: + word = el + count = len(el) + message = word + outputFile = open("./output_files/" + filename[:5] + ".txt", "w") + outputFile.write(message) + outputFile.close() + elif parsed[1] == "WCT": + count = 0 + for el in res: + count += eval(el) + message = str(count) + outputFile = open("./output_files/" + filename[:5] + ".txt", "w") + outputFile.write(message) + outputFile.close() + elif parsed[1] == "UPP" or parsed[1] == "LOW": + message = '' + for el in files: + file = open("./output_files/" + el[14:], 'r') + line = file.read(); + if line[-1] == "\n": + message += line + else: + message += line + " " + message = message[:-2] + outputFile = open("./output_files/" + filename[:5] + ".txt", "w") + outputFile.write(message) + outputFile.close() + + message = "REP " + parsed[1] + " " + parsed[2] + " " + message + + else: + message = "ERR" + + message += '\n' + print(">>> ", message) + sock.send(message.encode()) + sock.close() + +def registerWS(lst): + ptc = [] + i = 0 + while(len(lst[i]) == 3): + ptc += [lst[i]] + i += 1 + ws = [lst[i], lst[i+1], ptc] + return ws + +################################################################################ +# INICIO # +################################################################################ + +IP = socket.gethostbyname(socket.gethostname()) +PORT = 58023 + +BUFFER_SIZE = 1024 + +for i in range(len(sys.argv)): + if (sys.argv[i] == "-p"): + PORT = eval(sys.argv[i+1]) + +signal.signal(signal.SIGINT, signal_handler) + +try: + socketUSER = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +except socket.error: + print("Erro a criar socket!") + sys.exit(0) + +# Apaga os ficheiros nas pastas +files = glob.glob('./input_files/*.txt') +for f in files: + os.remove(f) + +files = glob.glob('./output_files/*.txt') +for f in files: + os.remove(f) + +try: + socketUSER.bind((IP, PORT)) +except socket.error: + print("Erro a criar socket!") + sys.exit(0) + +try: + socketUSER.listen(5) +except socket.error: + print("Erro a criar socket!") + sys.exit(0) + +try: + socketUDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +except socket.error: + print("Erro a criar socket!") + sys.exit(0) + +try: + socketUDP.bind((IP, PORT)) +except socket.error: + print("Erro a criar socket!") + sys.exit(0) + + +while(True): + r, w, e = select.select([socketUDP, socketUSER], [], []) + + if socketUSER in r: + try: + conn, addr = socketUSER.accept() + except socket.error: + print("Erro a aceitar socket!") + socketUSER.close() + socketUDP.close() + sys.exit(0) + + pidTCP = os.fork() + + if pidTCP < 0: + print("Erro no fork USER") + socketUDP.close() + socketUSER.close() + conn.close() + sys.exit(0) + + if pidTCP == 0: + socketUSER.close() + socketUDP.close() + doStuffUser(conn, addr, WSlist) + os._exit(0) + else: + conn.close() + continue + + + + elif socketUDP in r: + try: + data, addr = socketUDP.recvfrom(BUFFER_SIZE) + except socket.error: + socketUDP.close() + socketUSER.close() + print("Erro a receber") + + sys.exit(0) + parsed = str.split(data.decode()) + + if(parsed[0] == "REG"): + if len(WSlist) < 10: + ws = registerWS(parsed[1:]) + WSlist += [ws] + MESSAGE = "RAK OK\n" + res = "+ " + for el in ws[2]: + res += el + " " + res += ws[0] + " " + ws[1] + print(res) + else: + MESSAGE = "RAK NOK\n" + + + elif(parsed[0] == "UNR"): + delete = 0 + ipWS = parsed[1] + portWS = parsed[2] + for ws in WSlist: + if(ws[0] == ipWS and ws[1] == portWS): + delete = 1 + WSlist.remove(ws) + MESSAGE = "UAK OK\n" + res = "- " + for el in ws[2]: + res += el + " " + res += ipWS + " " + portWS + print(res) + if delete == 0: + MESSAGE = "UAK NOK\n" + else: + print("ERR") + socketUDP.close() + socketUSER.close() + sys.exit(0) + + try: + socketUDP.sendto(MESSAGE.encode(), addr) + except socket.error: + print("Erro a receber mensagem") + socketUDP.close() + socketUSER.close() + sys.exit(0) + + + continue; \ No newline at end of file diff --git a/proj2017/tcpClient.py b/proj2017/tcpClient.py new file mode 100644 index 0000000..88670e7 --- /dev/null +++ b/proj2017/tcpClient.py @@ -0,0 +1,14 @@ +import socket + +IP = socket.gethostbyname(socket.gethostname()) +PORT = 5005 + +MESSAGE = "Hello World!" + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect((IP, PORT)) +s.send(MESSAGE.encode()) +data = s.recv(1024).decode() +s.close() + +print ("received data:", data) \ No newline at end of file diff --git a/proj2017/tcpServer.py b/proj2017/tcpServer.py new file mode 100644 index 0000000..22e1b6b --- /dev/null +++ b/proj2017/tcpServer.py @@ -0,0 +1,16 @@ +import socket + +IP = socket.gethostbyname(socket.gethostname()) +PORT = 5005 + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.bind((IP, PORT)) +s.listen(1) + +conn, addr = s.accept() +print ('Connection address:', addr) + +data = conn.recv(20).decode() +print ("received data:", data) +conn.send(data.encode()) +conn.close() diff --git a/proj2017/udpClient.py b/proj2017/udpClient.py new file mode 100644 index 0000000..823e7ef --- /dev/null +++ b/proj2017/udpClient.py @@ -0,0 +1,12 @@ +import socket + +UDP_IP = "localhost" +UDP_PORT = 50823 +MESSAGE = "Hello World!" + +print("UDP target IP: ", UDP_IP) +print("UDP target port: ", UDP_PORT) +print("Message: ", MESSAGE) + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT)) \ No newline at end of file diff --git a/proj2017/udpServer.py b/proj2017/udpServer.py new file mode 100644 index 0000000..298505f --- /dev/null +++ b/proj2017/udpServer.py @@ -0,0 +1,11 @@ +import socket + +UDP_IP = 'localhost' +UDP_PORT = 50800 + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.bind((UDP_IP, UDP_PORT)) + +while (True): + data, addr = sock.recvfrom(1024) + print("Received message: ", data.decode()) \ No newline at end of file diff --git a/proj2017/user.py b/proj2017/user.py new file mode 100644 index 0000000..9f8c44d --- /dev/null +++ b/proj2017/user.py @@ -0,0 +1,144 @@ +################################################################################ +# USER APPLICATION # +################################################################################ +import socket +import sys +import signal +import os + +def signal_handler(signal, frame): + print("*** User is shutting down! ***") + s.close() + sys.exit(0) + + +################################################################################ +# INICIO # +################################################################################ + +signal.signal(signal.SIGINT, signal_handler) + +try: + TCP_IP = socket.gethostbyname(socket.gethostname()) +except socket.error: + print("Erro a obter IP a que vai ligar") + sys.exit + +TCP_PORT = "58023" +BUFFER_SIZE = 1024 +flagExit = 1 +ptc = "" +bytesToSend = 0 +bytesReceived = 0 + +for i in range(len(sys.argv)): + if (sys.argv[i] == "-n"): + TCP_IP = socket.gethostbyname(sys.argv[i+1]) + if (sys.argv[i] == "-p"): + TCP_PORT = sys.argv[i+1] + +while (flagExit): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + except socket.error: + print("Erro a criar socket!") + sys.exit(0) + + toRead = input("> ") + scan = str.split(toRead) + if (scan[0] == "exit"): + flagExit = 0 + break + elif (scan[0] == "list"): + message = "LST" + "\n" + elif (scan[0] == "request" and len(scan) == 3): + ptc = scan[1] + if not os.path.isfile(scan[2]): + print("Unknown file") + break + else: + f = open(scan[2]) + text = f.read() + bytesToSend = len(text.encode("utf-8")) + f.close() + message = "REQ " + ptc + " " + str(bytesToSend) + " " + text + "\n" + else: + print("Unknown command!") + continue + + try: + s.connect((TCP_IP,eval(TCP_PORT))) + except socket.error: + print("Erro a ligar ao servidor!") + s.close() + sys.exit(0) + + if ptc == "UPP" or ptc == "LOW": + print("" + str(bytesToSend) + " Bytes to transmit") + + try: + bytesSent = s.send(message.encode()) + except socket.error: + print("Erro a enviar mensagem!") + s.close() + sys.exit(0) + + try: + data = s.recv(BUFFER_SIZE).decode() + + while(data[-1] != "\n"): + data += s.recv(BUFFER_SIZE).decode() + except socket.error: + print("Erro a receber mensagem!") + s.close() + sys.exit(0) + + data = data[:-1] + dataParsed = data.split(' ') + res = '' + + if dataParsed[0] == "FPT" and dataParsed[1] == "EOF": + res = "No servers available\n" + + elif dataParsed[0] == "FPT": + i = 0 + for i in range(eval(dataParsed[1])): + if dataParsed[i+2] == "FLW": + res += ' ' + str(i+1) + "- " + dataParsed[i+2] + " - find longest word" + "\n" + elif dataParsed[i+2] == "WCT": + res += ' ' + str(i+1) + "- " + dataParsed[i+2] + " - word count" + "\n" + elif dataParsed[i+2] == "UPP": + res += ' ' + str(i+1) + "- " + dataParsed[i+2] + " - convert to upper case" + "\n" + elif dataParsed[i+2] == "LOW": + res += ' ' + str(i+1) + "- " + dataParsed[i+2] + " - convert to lower case" + "\n" + else: + res = "FPT ERR" + print(res) + s.close() + sys.exit(0) + + elif dataParsed[0] == "REP": + if ptc == "WCT": + res += " Number of words: " + dataParsed[3] + elif ptc == "FLW": + res += " Longest word: " + dataParsed[3] + elif ptc == "UPP" or ptc == "LOW": + res += " received " + dataParsed[2] + " Bytes\n" + for el in dataParsed[3:]: + res += el + " " + else: + res = "REP EOF" + print(res) + s.close() + sys.exit(0) + + + else: + res = "ERR" + print(res) + s.close() + sys.exit(0) + + res += '\n' + print(res) + s.close() \ No newline at end of file diff --git a/proj2017/ws.py b/proj2017/ws.py new file mode 100644 index 0000000..6b697b8 --- /dev/null +++ b/proj2017/ws.py @@ -0,0 +1,235 @@ +################################################################################ +# WORKING SERVER # +################################################################################ + +import socket +import sys +import signal + +################################################################################ +# VARIAVEIS # +################################################################################ +CSname = socket.gethostname() +WSport = 59000 +CSport = 58023 +MESSAGE = '' +ptc = [] +BUFFER = '' +registered = False +tcpOpen = False + +################################################################################ +# FUNCOES # +################################################################################ + +def signal_handler(signal, frame): + """ + Desregista o WS do CS e fecha as comunicaƧoes no caso de SIGIINT + """ + print("*** Working Server is shutting down! ***") + + socketUSER.close() + if registered == True: + unregisterWS(MESSAGE) + sys.exit(0) + +def registerWS(MESSAGE): + """ + Envia a mensagem de registo do WS e recebe o status do TCP + """ + MESSAGE = '' + MESSAGE = 'REG ' + for i in ptc: + MESSAGE += i + ' ' + + MESSAGE += socket.gethostbyname(socket.gethostname()) + ' ' + str(WSport) + '\n' + + try: + s.sendto(MESSAGE.encode(), (CSname, CSport)) + except socket.error: + print("Erro a enviar!") + s.close() + sys.exit(0) + + #verificar tamanho + try: + BUFFER, addr = s.recvfrom(1024) + except socket.error: + print("Erro a receber!") + s.close() + sys.exit(0) + + if BUFFER[4:] == 'NOK': + unregisterWS(MESSAGE) + + return True + +def unregisterWS(MESSAGE): + """ + Envia a mensagem de deregisto do WS, recebe o status do TCP e fecha o UDP + """ + MESSAGE = '' + MESSAGE = 'UNR ' + socket.gethostbyname(socket.gethostname()) + ' ' + str(WSport) + '\n' + + try: + s.sendto(MESSAGE.encode(), (CSname, CSport)) + except socket.error: + print("Erro a enviar!") + s.close() + sys.exit(0) + + + try: + s.settimeout(1) + BUFFER, addr = s.recvfrom(1024) + except socket.error: + print("Erro a receber!") + s.close() + sys.exit(0) + + +def processRequest(ptcCode, filename, size, data): + """ + Processa o pedido mandado pelo CS e devolve a resposta a ser devolvida pelo WS + """ + if not isinstance(eval(size), int): + reply = "REP ERR\n" + return reply + + reply = '' + if ptcCode == 'LOW': + text = '' + for i in data: + text += i + ' ' + text = text[:-2] + print(ptcCode, ":", filename[14:]) + print(' ', size, "bytes received") + print(' ', filename[14:], str(len(text.encode('utf-8'))), "bytes") + reply = 'REP F ' + str(len(text.encode('utf-8'))) + ' ' + text.lower() + '\n' + elif ptcCode == 'UPP': + text = '' + for i in data: + text += i + ' ' + text = text[:-2] + print(ptcCode, ":", filename[14:]) + print(' ', size, "bytes received") + print(' ', filename[14:], str(len(text.encode('utf-8'))), "bytes") + reply = 'REP F ' + str(len(text.encode('utf-8'))) + ' ' + text.upper() + '\n' + + elif ptcCode == 'FLW': + text = '' + for i in data: + text += i + ' ' + text = text[:-2] + parse = text.split() + longest = parse[0] + for i in parse: + if len(i) > len(longest): + longest = i + print(ptcCode, ":", filename[14:]) + print(' Longest word:', longest) + reply = 'REP R ' + str(len(longest.encode('utf-8'))) + ' ' + longest + '\n' + elif ptcCode == 'WCT': + count = 0 + text = '' + for i in data: + text += i + ' ' + parse = text.split() + for i in parse: + if (i[0] >= 'A' and i[0] <= 'Z') or (i[0] >= 'a' and i[0] <= 'z' or (i[0] >= '1' and i[0] <= '9')): + count += 1 + print(ptcCode, ":", filename[14:]) + print(' Number of words:', str(count)) + reply = 'REP R ' + str(len(str(count))) + ' ' + str(count) + '\n' + else: + reply = 'REP EOF\n' + + return reply + + +################################################################################ +# INICIO # +################################################################################ + +signal.signal(signal.SIGINT, signal_handler) + +for i in range(len(sys.argv)): + if len(sys.argv[i]) == 3: + ptc += [sys.argv[i]] + if sys.argv[i] == '-n': + CSname = sys.argv[i+1] + if sys.argv[i] == '-p': + WSport = eval(sys.argv[i+1]) + if sys.argv[i] == '-e': + CSport = eval(sys.argv[i+1]) + +try: + s = socket.socket(socket.AF_INET, # Internet + socket.SOCK_DGRAM) # UDP +except socket.error: + print("Erro a criar socket!") + sys.exit(0) + +try: + socketUSER = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +except socket.error: + print("Erro a criar socket!") + unregisterWS(MESSAGE) + sys.exit(0) + + +registered = registerWS(MESSAGE) + + +try: + socketUSER.bind((socket.gethostbyname(socket.gethostname()), WSport)) +except socket.error: + print("Erro a criar socket!") + unregisterWS(MESSAGE) + sys.exit(0) + +try: + socketUSER.listen(1) +except socket.error: + print("Erro a criar socket!") + unregisterWS(MESSAGE) + sys.exit(0) + +while True: + + try: + conn, addr = socketUSER.accept() + except socket.error: + print("Erro a aceitar socket!") + unregisterWS(MESSAGE) + sys.exit(0) + + try: + BUFFER = conn.recv(1024).decode() + except socket.error: + print("Erro a enviar!") + unregisterWS(MESSAGE) + socketUSER.close() + sys.exit(0) + + command = BUFFER.split(' ') + + if command[0] == 'WRQ': + if command[1] in ptc: + MESSAGE = processRequest(command[1], command[2], command[3], command[4:]) + else: + MESSAGE = 'REQ EOF\n' + else: + MESSAGE = 'ERR\n' + + try: + conn.send(MESSAGE.encode()) + except socket.error: + print("Erro a receber!") + unregisterWS(MESSAGE) + socketUSER.close() + sys.exit(0) + +conn.close() +tcpOpen = False +unregisterWS(MESSAGE)