I've programmed a python script to backup my files, something like Dropbox.
But there are some bugs. I have a class called SyncServer, and there are two functions called __init__ and TF1 seperately. TF1 stands for "Thread Function 1".
When I write thread.start_new_thread(TF1, (conn, 0)), the first parameter, I sent a socket object in. Unfortunately, python's IDLE replied with an error: NameError: global name 'TF1' is not defined
# -*- coding: cp950 -*-
import wx, socket, os, md5, thread, threading
class SyncClient:HOST = "127.0.0.1"
def __init__(self):
self.config = {}
open("sync.config", "a").close()
f = open("sync.config", "r")
line = f.readline()
while line:
tmp = line.split(":")
self.config[tmp[0]] = ":".join(tmp[1:]).split("\n")[0]
line = f.readline()
f.close()
ex = wx.App()
ex.MainLoop()
if (not self.config.has_key("id")) or (not self.config.has_key("password")) or (not self.config.has_key("port")) or (not self.config.has_key("path")):
wx.MessageBox('something wrong. Q__________________________Q', 'Error',
wx.OK | wx.ICON_ERROR)
return
if (not os.access(self.config["path"], os.F_OK)):
wx.MessageBox("It seems that " + self.config["path"] + " doesn't exist.", 'Error',
wx.OK | wx.ICON_ERROR)
return
if int(self.config['port']) > 5:
wx.MessageBox('something wrong. Q__________________________Q', 'Error',
wx.OK | wx.ICON_ERROR)
return
chpswd = md5.new(self.config['password']).hexdigest()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.HOST, 7575))
self.s = s;
s.send("CHECK ID")
if s.recv(1024) != "200 OK":
return
s.send(config['id'] + ";;" + chpswd)
if s.recv(1024) == "False":
wx.MessageBox("id and password not match.", 'Error',
wx.OK | wx.ICON_ERROR)
return
self.path = []
for root, dirs, files in os.walk(self.config['path']):
for f in files:
self.path.append(root + f)
self.s.send("FILE NAME")
if self.s.recv(1024) != "200 OK":
continue
self.s.send(f)
if self.s.recv(1024) != "200 OK":
continue
self.s.send("FILE LEN")
if self.s.recv(1024) != "200 OK":
continue
cut = file_cut(root + f)
self.s.send(len(cut))
MakeThread(cut)
def MakeSocket(self):
self.s.send("GIVE ME A PORT")
port = int(self.s.recv(1024))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.HOST, port))
return s
def MakeThread(self, cut):
self.ptr = 0
s = MakeSocket()
for i in self.config['port']:
#s = MakeSocket()
thread.start_new_thread(TF, (s, cut))
def TF(self, Socket, cut):
l = len(cut)
while self.ptr < l:
Socket.send(self.ptr)
if Socket.recv(1024) != "200 OK":
continue
Socket.send(cut[self.ptr])
self.ptr += 1
Socket.close()
def file_cut(self, path):
f = open(path, "rb")
content = f.read()
cut = []
l = len(content)
i = 0
while i < l:
cut.append(content[i:i+1024])
i += 1024
return cut
'''f = open(path, "rb")
cont = f.read()
f.close()
fsize = len(cont)
fname = path.split("\\")[-1]
self.com.send(fname)
check = self.com.recv(1024)
if check != "200 OK": return
self.com.send(str(fsize))
check = self.com.recv(1024)
if check != "200 OK": return
i = 0
while i < fsize + 1025:
Socket.send(cont[i:i+1024])
i += 1024'''
def file_recv(self, Socket, path=".\\"):
fname = self.com.recv(1024)
self.com.send("200 OK")
f = open(path + fname, "wb")
fsize = self.com.recv(1024)
self.com.send("200 OK")
i = 0
while i < fsize + 1025:
line = Socket.recv(1024)
f.write(line)
f.flush()
i += 1024
f.close()
class SyncServer:
def TF1(self, Socket, null):
while True:
data = Socket.recv(1024)
if data == "CHECK ID":
Socket.send("200 OK!")
user = Socket.recv(1024)
u = open("uid.txt","r")
while True:
udata = u.readline().split(" ")
if udata == "":
Socket.send("False")
break
if user.split(";;")[0] == udata[0]:
Flag = True
if user.split(";;")[1] != md5.hexidigest(udata[1]):
Socket.send("False")
else:
self.user = user.split(";;")[0]
self.files[self.user] = []
Socket.send("True")
break
if data == "GIVE ME A PORT":
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", self.portList[0]))
s.listen(1)
Socket.send(self.portList[0])
for i in range(0, flen):
thread.start_new_thread(TF2, (s.accept(), 0))
f = open(fname, "wb")
for line in self.files[self.user]:
f.write(line)
f.close()
#self.port
if data == "FILE NAME":
Socket.send("200 OK")
fname = Socket.recv(1024)
Socket.send("200 OK")
if data == "FILE LEN":
Socket.send("200 OK")
flen = int(Socket.recv(1024))
def TF2(self, Socket, null):
idx = Socket.recv(1024)
Socket.send("200 OK")
line = Socket.recv(1024)
self.files[self.user][idx] = line
def __init__(self):
self.portList = []
self.files = {}
for i in range(7576,7700):
self.portList.append(i)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 7575))
s.listen(1)
while True:
conn, addr = s.accept()
thread.start_new_thread(TF1, (conn, 0))
thread.start_new_thread(TF1, (conn, 0))
Assumes that TF1 is a global.
"NameError: global name 'TF1' is not defined"
States that TF1 is not a global.
It must be that the assumption is wrong.
TF1 is a method function in a class. Therefore, it needs to be qualified either by the class name or by an object instance. Usually, self.TF1 is appropriate.
Please find a Python tutorial where class definitions are covered.
Related
I am implementing an authentication process between a server and a client in order to exchange some information. I have created a function called serverToClientAuth on both server and client that carries out a basic back and forth communication to establish authenticated integrity checks of each other before exchanging some data.
When I run the server, followed by the client, the exchange occurs perfectly with encryption and hashing working as required but on the very last message from the server to the Client, the client seems to hang and is unable to exit the function and go back to normal operation Although the first 3 communications work fine, the last one does not for some reason.
I thought at first that it had something to do with the encryption/Decryption functions but as the first 3 operations work, I don't see why the last doesn't? It seems that the recieve_msg function is grabbing the last message instead of the authentication function, this is the final '12' output on the client window as seen below.
I have included both the server and client as well as the output of each below. If anyone has any idea as to why this hang is occurring, it would be greatly appreciated.
#Server.py
from socket import AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, socket
from threading import Thread
from signal import signal, SIGINT
import sys
import os
import random
import rsa
WELCOME_MSG = 'Server is active and awaiting connections'
def nonceGenerator():
num = ""
for i in range(5):
rand = random.randint(0,1)
num += str(rand)
return num
def generateAKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/APubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/APrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateBKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/BPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/BPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateCKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/CPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/CPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateSKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/SPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/SPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def loadKeys():
with open('keys/SPubKey.pem', 'rb') as p:
SPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/SPrivKey.pem', 'rb') as p:
SPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/APubKey.pem', 'rb') as p:
APubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/APrivKey.pem', 'rb') as p:
APrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/BPubKey.pem', 'rb') as p:
BPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/BPrivKey.pem', 'rb') as p:
BPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/CPubKey.pem', 'rb') as p:
CPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/CPrivKey.pem', 'rb') as p:
CPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
return SPubKey, SPrivKey, APubKey, APrivKey, BPubKey, BPrivKey, CPubKey, CPrivKey
def encrypt(message, key):
return rsa.encrypt(message.encode('utf8'), key)
def decrypt(ciphertext, key):
try:
return rsa.decrypt(ciphertext, key).decode('utf8')
except:
return False
def sign(message, key):
return rsa.sign(message.encode('utf8'), key, 'SHA-1')
def verify(message, signature, key):
try:
return rsa.verify(message.encode('utf8'), signature, key,) == 'SHA-1'
except:
return False
def incoming_connections():
while True:
client, addr = SERVER.accept()
print(f'A client has connected {addr}')
# client.send(WELCOME_MSG.encode())
Thread(target=single_client, args=(client,)).start()
print('Client connected')
def single_client(client):
client_name = client.recv(BUFFERSIZE).decode()
#client_name = 'Anonymous'
welcome_msg = f'Welcome {client_name}.\nType exit() or press CTRL+D or CTRL+C to exit.\n'
client.send(welcome_msg.encode())
chat_msg = f'{client_name} has joined the room'
broadcast_msg(chat_msg.encode())
clients[client] = client_name
serverToClientAuth(client) #Begin Authentication process upon reciving client
while True:
msg = client.recv(BUFFERSIZE)
if msg == 'online()'.encode('utf8'):
real_clients_num, real_clients_name = get_clients()
client.send(f'Online users {real_clients_num} : {real_clients_name}'.encode('utf8'))
elif msg == EXIT_CMD.encode('utf8'):
print(f'{clients[client]} has disconnected ')
client.send('You are leaving the room...'.encode())
client.close()
client_leaving = clients[client]
del clients[client]
broadcast_msg(f'{client_leaving} has left the room!'.encode())
break
elif '#'.encode('utf8') in msg:
unicast_msg(msg, client)
else:
broadcast_msg(msg, clients[client] + ': ')
def get_clients():
real_clients_num = 0
real_clients_name = []
for k,v in clients.items():
if v != 'Anonymous':
real_clients_num += 1
real_clients_name.append(v)
return real_clients_num, real_clients_name
def broadcast_msg(msg, name=""):
for client in clients:
client.send(name.encode() + msg)
def unicast_msg(msg, client):
# Get only name by removing #
msg = msg.decode('utf8')
refered_client, client_msg = msg.split(' ',1)
client_to_connect = refered_client.strip('#')
for k,v in clients.items():
if v == client_to_connect:
k.send(f'{clients[client]} -> {client_to_connect}: {client_msg}'.encode('utf8'))
def receive_msg():
while True:
try:
msg = client_socket.recv(BUFFERSIZE).decode("utf8")
print(msg)
except OSError as error:
return error
def serverToClientAuth(client):
Ka=bytes('1', 'utf8')
Kb=bytes('2', 'utf8')
Kc=3
user = clients[client] #A, B or C
message1 = client.recv(1024) #Nonce Na, Nb or Nc
NEnc, sig1 = message1[:128], message1[128:]
N = decrypt(NEnc, SPrivKey)
if verify(N, sig1, APubKey):
Ns = nonceGenerator() #Servers Nonce
NNs = "{}|{}".format(N, Ns)
NNsEnc = encrypt(NNs, APubKey)
sig2 = sign(NNs, SPrivKey)
message2 = NNsEnc + sig2
client.send(message2)
message3 = client.recv(1024)
NsXX = decrypt(message3, SPrivKey)
print(NsXX)
NsXX = NsXX.split("|")
if NsXX[0] == Ns: #Does the Nonce that client returned match what was sent?
if NsXX[1] == 'B' and NsXX[2] == 'C':
message4 = Ka + Kb
client.send(message4)
print("Client " + user + " has been authenticated to the server\n")
elif NsXX[1] == 'A' and NsXX[2] == 'C':
message4 = "{}|{}".format(Ka, Kc)
client.send(message4.encode('utf8'))
print("Client " + user + " has been authenticated to the server\n")
elif NsXX[1] == 'A' and NsXX[2] == 'B':
message4 = "{}|{}".format(Ka, Kb)
client.send(message4.encode('utf8'))
print("Client " + user + " has been authenticated to the server\n")
else:
print("Unrecognised identifier")
else:
print("Replied nonce from Client does not match")
else:
print('The message signature could not be verified')
if __name__ == "__main__":
clients = {}
generateAKeys()
generateBKeys()
generateCKeys()
generateSKeys()
SPubKey, SPrivKey, APubKey, APrivKey, BPubKey, BPrivKey, CPubKey, CPrivKey = loadKeys()
HOST = '127.0.0.1'
PORT = 5000
BUFFERSIZE = 1024
ADDR = (HOST, PORT)
EXIT_CMD = "exit()"
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
SERVER.bind(ADDR)
SERVER.listen(2)
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=incoming_connections)
ACCEPT_THREAD.start()
ACCEPT_THREAD.join()
SERVER.close()
The server file ^^^
#Client A
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
from signal import signal, SIGINT
import sys
import os
import random
import rsa
def nonceGenerator():
num = ""
for i in range(5):
rand = random.randint(0,1)
num += str(rand)
return num
def loadKeys():
with open('keys/APubKey.pem', 'rb') as p:
APubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/APrivKey.pem', 'rb') as p:
APrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/SPubKey.pem', 'rb') as p:
SPubKey = rsa.PublicKey.load_pkcs1(p.read())
return APubKey, APrivKey, SPubKey
def encrypt(message, key):
return rsa.encrypt(message.encode('utf8'), key)
def decrypt(ciphertext, key):
try:
return rsa.decrypt(ciphertext, key).decode('utf8')
except:
return False
def sign(message, key):
return rsa.sign(message.encode('utf8'), key, 'SHA-1')
def verify(message, signature, key):
try:
return rsa.verify(message.encode('utf8'), signature, key,) == 'SHA-1'
except:
return False
def receive_msg():
while True:
try:
msg = client_socket.recv(BUFFERSIZE).decode("utf8")
print(msg)
except OSError as error:
return error
def keyBoard_Input():
while True:
try:
msg = input()
if msg != 'exit()':
client_socket.send(msg.encode('utf8'))
else:
clean_exit()
except EOFError:
clean_exit()
def send_msg(data):
try:
msg = data
if msg != 'exit()':
client_socket.send(msg.encode('utf8'))
else:
clean_exit()
except EOFError:
clean_exit()
def clean_exit():
client_socket.send('exit()'.encode('utf8'))
client_socket.close()
sys.exit(0)
def handler(signal_received, frame):
clean_exit()
def serverToClientAuth(client):
Na = nonceGenerator()
NaEnc = encrypt(Na, SPubKey)
sig1 = sign(Na, APrivKey)
message1 = NaEnc + sig1
client_socket.send(message1)
message2 = client_socket.recv(1024)
NaNsEnc, sig2 = message2[:128], message2[128:]
NaNs = decrypt(NaNsEnc, APrivKey)
if verify(NaNs, sig2, SPubKey):
NaNs = NaNs.split("|")
if NaNs[0] == Na:
Ns = NaNs[1]
print(Ns)
NsBC = "{}|{}|{}".format(Ns, 'B', 'C')
NsBCEnc = encrypt(NsBC, SPubKey) #No signature needed anymore
message3 = NsBCEnc
client_socket.send(message3)
print('Client gets stuick here')
message4 = client_socket.recv(1024)
print(message4)
message4 = message4.split("|")
APubKey, CPubKey = message3[0], message3[1]
print("Client B is Authenticated to the Server")
print("Ka = " + APubKey)
print("Kc = " + CPubKey)
else:
print("Replied nonce from server does not match")
else:
print('The message signature could not be verified')
if __name__ == '__main__':
signal(SIGINT, handler)
HOST = '127.0.0.1'
PORT = 5000
BUFFERSIZE = 1024
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive_msg)
receive_thread.start()
APubKey, APrivKey, SPubKey = loadKeys()
send_msg('A') #Assign Client ID at the moment the connection is initiated
serverToClientAuth(client_socket)
keyBoard_Input()
Client File ^^^^
Waiting for connection...
A client has connected ('127.0.0.1', 51407)
Client connected
01001|B|C
Client A has been authenticated to the server
Server response ^^^
Welcome A.
Type exit() or press CTRL+D or CTRL+C to exit.
01001
Client gets stuick here
12
Client Response ^^^
The '12' displayed here should be a '1|2' as that is the message sent by the server. However, it seems that the receive_msg function is actually taking the message instead of the function, causing the function to hang and wait for a message.
I have a client that let user to browse a file and upload to a server. Currently I'm just using command terminal to operate the program. When user type in fup in the terminal , the program will ask for filename and the file will be upload to the server if the filename input by user is valid.
So, what i want now is letting user to browse any file directory from a GUI without typing the filename to upload. I've tried to implement filedialog but it seem like not working, when i browse and upload a file, the server does not received any new file. I stucked with issues almost a week already but still couldn't find any solution, hope someone could help me. Thanks in advance
Client.py
import socket, sys, os
import time, shutil
# socket creating
def sock():
try:
s = socket.socket()
host = input('Enter Target IP :')
port = 9999
s.connect((host, port))
return (host, s)
except:
print("Error: In binding")
sock()
host, s = sock()
# upload file to client
def fup(conn):
try:
filename = input("\nMANO >>Filename? -> ")
if os.path.isfile(filename):
conn.send(str("fup~" + filename).encode("utf-8"))
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
sys.stdout.write("\r|" + "█" * int((totalSend / float(filesize)) * 50) + "|{0:.2f}".format(
(totalSend / float(filesize)) * 100) + "% ")
sys.stdout.flush()
print("\nUpload Completed!")
else:
print("File Does Not Exist!")
except:
print("Error")
# download file from client
def fdown(conn):
try:
print(os.getcwd())
filename = input("\nMANO >>Filename? -> ")
if filename != 'q':
conn.send(("fdown~" + filename).encode("utf-8"))
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
msg = input("File exists, " + str(filesize) + "Bytes, download? (Y/N)? -> ").upper()
if msg == 'Y':
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
sys.stdout.write("\r|" + "█" * int((totalRecv / float(filesize)) * 50) + "|{0:.2f}".format(
(totalRecv / float(filesize)) * 100) + "% ")
sys.stdout.flush()
time.sleep(0.01)
print("\nDownload Complete!")
f.close()
else:
print("File Does Not Exist!")
except:
print("Error")
# commands that perform on client
def mano(cip, conn):
while True:
cli = input("MANO >>" + cip + ' >>')
if cli == 'fdown':
fdown(conn)
elif cli == 'fup':
fup(conn)
else:
print("Command not recognized")
mano(host, s)
Server.py
import socket, os, subprocess, shutil, pickle, struct, threading
## gettig the hostname by socket.gethostname() method
hostname = socket.gethostname()
## getting the IP address using socket.gethostbyname() method
ip_address = socket.gethostbyname(hostname)
# Create a Socket ( connect two computers)
def create_socket():
try:
global host
global port
global s
host = ""
port = 9999
s = socket.socket()
except socket.error as msg:
create_socket()
# Binding the socket and listening for connections
def bind_socket():
try:
global host
global port
global s
s.bind((host, port))
s.listen(5)
## printing the hostname and ip_address
print(f"Hostname: {hostname}")
print(f"IP Address: {ip_address}")
print(f"Running Port: {port}")
except socket.error as msg:
bind_socket()
print(bind_socket())
# send file list
def flist(conn):
try:
arr = pickle.dumps(os.listdir())
conn.send(arr)
print(arr)
except:
conn.send(('Error').encode("utf-8"))
# accept file from server
def fdown(filename, conn):
try:
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
f.close()
except:
conn.send(('Error').encode("utf-8"))
# send file
def fup(filename, conn):
if os.path.isfile(filename):
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
else:
conn.send("ERROR".encode("utf-8"))
# main
def main(s):
while True:
data = (s.recv(1024)).decode("utf-8").split('~')
if data[0] == 'fdown':
fup(data[1], s)
elif data[0] == 'fup':
fdown(data[1], s)
elif data[0] == 'flist':
flist(s)
else:
s.send(".".encode('utf-8'))
def socket_accept():
while True:
conn, address = s.accept()
t = threading.Thread(target=main, args=(conn,))
t.start()
create_socket()
bind_socket()
socket_accept()
Expected output:
since you are using a gui I think you should receive the inputs through the use of an tkinter.Entry widget not through the terminal with input()
I made a python file server a while back and just recently came back to it. It is a very simple program but i wanted to add some more features to it, one of those being to add some security. For this reason i made a hashed login password and put that in a .txt file stored on the server computer. The way the program is supposed to work is every time the client connects to the server they must enter a password. Then the raw_entry is sent through a socket and checked on the server side if it is correct, if is is not then the user has two more tries to enter the password. For some reason this is not working.
The server:
from passlib.hash import pbkdf2_sha256
import socket
import threading
import os
def login():
loop = 1
while loop <= 3:
passwd = sock.recv(1024)
with open('passtor.txt', 'r') as f:
hash = f.read()
if pbkdf2_sha256.verify(passwd, hash):
s.send("Access Granted")
loop = 4
else:
s.send("Verification Failure")
loop += 1
if loop == 3:
sock.close()
def RetrFile(name, sock):
filename = sock.recv(1024)
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send("ERR ")
sock.close()
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#s.connect(('google.com', 0))
host = s.getsockname()[0]
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(5)
print "File Server Initiated"
print("Server Address-> " + host + " <-")
while True:
c, addr = s.accept()
print "Client Connected ip-> " + str(addr) + " <-"
t1 = threading.Thread(target=login, args=("RetrThread", c))
t2 = threading.Thread(target=RetrFile, args=("RetrThread", c))
t1.start()
t2.start()
s.close()
except:
print("Program Error, \nTermination Complete")
The client:
import socket
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.connect((host, port))
loop = True
while loop == True:
passwd = raw_input("Admin Password-> ")
s.send(passwd)
answer = s.recv(1024)
if answer == 'Verification Failure':
loop = True
print(answer)
elif answer == 'Access Granted':
loop = False
print(answer)
filename = raw_input("Filename? -> ")
if filename != 'q':
s.send(filename)
data = s.recv(1024)
if data[:6] == 'EXISTS':
filesize = long(data[6:])
message = raw_input("File exists, " + str(filesize) +"Bytes, download? (Y/N)? -> ")
if message == 'Y':
s.send("OK")
f = open('new_'+filename, 'wb')
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while totalRecv < filesize:
data = s.recv(1024)
totalRecv += len(data)
f.write(data)
print "{0:.2f}".format((totalRecv/float(filesize))*100)+ "% Done"
print "Download Complete!"
f.close()
else:
print "File Does Not Exist!"
s.close()
You are passing two arguments to the login function here:
t1 = threading.Thread(target=login, args=("RetrThread", c))
They are not declared in the function declaration:
def login():
Either remove the args parameter from the call to threading.Thread or add the arguments to the function declaration.
I am learning Python right now, and try to write a small file transfer program. The following is my codes.
This is the server codes
import SocketServer
import commands, time
class MySockServer(SocketServer.BaseRequestHandler):
def recv_all(self,obj, msg_length, des_file):
while msg_length != 0:
if msg_length <= 1024:
print 'here3'
print msg_length
print type(msg_length)
data = obj.recv(msg_length)
print data
msg_length = 0
print 'here4'
break
else:
data = obj.recv(1024)
msg_length -= 1024
#print msg_length
des_file.write(data)
print 'here4'
return 'Done'
def handle(self):
print 'Got a new conn from', self.client_address
while True:
cmd = self.request.recv(1024)#receive data from client
print cmd
if not cmd:#deal with ctrl+c from client
print 'Lost connection'
break
CMD = cmd.split()
print CMD
option, filename, file_size = CMD[:3]
print option
print filename
print file_size
if option == 'put':
#client wants to upload file
f = file('temp/%s' % filename, 'wb')
print 'here'
write_to_file = self.recv_all(self.request, int(file_size), f)
print 'here1'
if write_to_file == 'Done':
f.close()
self.request.send('File uploading done')
if __name__ == '__main__':
h = '0.0.0.0'
p = 9002
s = SocketServer.ThreadingTCPServer((h,p),MySockServer)
s.serve_forever()
The client codes:
import socket, os
host,port = '192.168.73.11', 9002
c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
c.connect((host,port))
while True:
user_input = raw_input('msg to send:: ').strip()
if len(user_input) == 0: continue
user_cmd = user_input.split()
if user_cmd[0] == 'put':
if len(user_cmd) == 2:
f = file(user_cmd[1], 'rb')
f_size = os.path.getsize(user_cmd[1])
print user_cmd[0], user_cmd[1], str(f_size)
c.send('%s %s %s ' % (user_cmd[0],user_cmd[1],f_size))
print 'going to send....'
c.sendall(f.read())
print c.recv(1024)
c.close()
I just inserted some prints into the codes to find where are the problems. I found that in the recv_all() function in server codes, the sentence 'data = obj.recv(msg_length)' in the 'if' part cannot work, but the sentence in the 'else' part works very well. Is there anyone can tell me why could this happen?
Thanks guys.
So the curl command I'm using is as follows:
cmd = "curl --write-out %{http_code} -X PUT -T " + self.basedir + putfile + " -# -o /dev/null " + self.uri + "/" + self.dist + "/" + putfile
I'd like to change this from invoking a system command to using pycurl. This way I can have more granular control over it and ultimately implement a progress bar for it. However, when I try and convert to python, my resulting script fails. Here is my efforts towards a python script:
f = open(filepath, "rb")
fs = os.path.getsize(filepath)
c = pycurl.Curl()
c.setopt(c.URL, target_url)
c.setopt(c.HTTPHEADER, ["User-Agent: Load Tool (PyCURL Load Tool)"])
c.setopt(c.PUT, 1)
c.setopt(c.READDATA, f)
c.setopt(c.INFILESIZE, int(fs))
c.setopt(c.NOSIGNAL, 1)
c.setopt(c.VERBOSE, 1)
c.body = StringIO()
c.setopt(c.WRITEFUNCTION, c.body.write)
try:
c.perform()
except:
import traceback
traceback.print_exc(file=sys.stderr)
sys.stderr.flush()
f.close()
c.close()
sys.stdout.write(".")
sys.stdout.flush()
Here's what that outputs:
* About to connect() to ************ port 8090 (#0)
* Trying 16.94.124.53... * connected
> PUT /incoming/ HTTP/1.1
Host: ***********
Accept: */*
User-Agent: Load Tool (PyCURL Load Tool)
Content-Length: 21
Expect: 100-continue
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 500 Internal Server Error
< Content-type: text/html
* no chunk, no close, no size. Assume close to signal end
<
Thanks in advance for you help!
I've did uploading working module, you can find your answers looking in code.
And you can find almost all answers regarding pycurl by digging libcurl examples and Docs.
'''
Created on Oct 22, 2013
#author: me
'''
import pycurl
import os
import wx
import sys
import hashlib
from cStringIO import StringIO
def get_file_hash(full_filename):
BLOCKSIZE = 65536
hasher = hashlib.md5()
with open(full_filename, 'rb') as afile:
buf = afile.read(BLOCKSIZE)
while len(buf) > 0:
hasher.update(buf)
buf = afile.read(BLOCKSIZE)
return hasher.hexdigest()
class FtpUpload(object):
def __init__(self, server, username, password, **items):
self.server = server
self.username = username
self.password = password
self.gauge = items.get("gauge")
self.sb_speed = items.get("sb_speed")
self.upload_file_size = items.get("upload_file_size")
self.upload_file_speed = items.get("upload_file_speed")
self.filesize = 0
self.ftp_filehash = '0'
def sizeToNiceString(self, byteCount):
for (cutoff, label) in [(1024*1024*1024, "GB"), (1024*1024, "MB"), (1024, "KB")]:
if byteCount >= cutoff:
return "%.2f %s" % (byteCount * 1.0 / cutoff, label)
if byteCount == 1:
return "1 byte"
else:
return "%d bytes" % byteCount
def initRange(self, filesize):
self.filesize = filesize
self.gauge.SetRange(filesize)
def updateValue(self, upload_d):
upload_d_int = int(upload_d)
self.gauge.SetValue(upload_d_int)
upload_d_str = self.sizeToNiceString(upload_d)
upload_percent = int((upload_d*100)/self.filesize)
upload_d_status = "{0}/{1} ({2}%)".format(upload_d_str, self.sizeToNiceString(self.filesize), upload_percent)
self.sb_speed.SetStatusText(upload_d_status, 1)
self.upload_file_size.SetLabel(upload_d_status)
self.upload_file_speed.SetLabel(upload_d_str)
def progress(self, download_t, download_d, upload_t, upload_d):
self.updateValue(upload_d)
def test(self, debug_type, debug_msg):
if len(debug_msg) < 300:
print "debug(%d): %s" % (debug_type, debug_msg.strip())
def ftp_file_hash(self, buf):
sys.stderr.write("{0:.<20} : {1}\n".format('FTP RAW ', buf.strip()))
ftp_filehash = dict()
item = buf.strip().split('\n')[0]
ext = item.split('.')[1]
if len(ext) > 3:
ftp_filename = item[:-33]
ftp_filehash = item[-32:]
self.ftp_filehash = ftp_filehash
def get_ftp_file_hash(self, filename):
c = pycurl.Curl()
list_file_hash = 'LIST -1 ' + filename + "_*"
sys.stderr.write("{0:.<20} : {1} \n".format('FTP command ', list_file_hash))
c.setopt(pycurl.URL, self.server)
c.setopt(pycurl.USERNAME, self.username)
c.setopt(pycurl.PASSWORD, self.password)
c.setopt(pycurl.VERBOSE, False)
c.setopt(pycurl.DEBUGFUNCTION, self.test)
c.setopt(pycurl.CUSTOMREQUEST, list_file_hash)
c.setopt(pycurl.WRITEFUNCTION, self.ftp_file_hash)
c.perform()
c.close()
def delete_ftp_hash_file(self, ftp_hash_file_old):
c = pycurl.Curl()
delete_hash_file = 'DELE ' + ftp_hash_file_old
sys.stderr.write("{0:.<20} : {1} \n".format('FTP command ', delete_hash_file))
c.setopt(pycurl.URL, self.server)
c.setopt(pycurl.USERNAME, self.username)
c.setopt(pycurl.PASSWORD, self.password)
c.setopt(pycurl.VERBOSE, False)
c.setopt(pycurl.DEBUGFUNCTION, self.test)
c.setopt(pycurl.CUSTOMREQUEST, delete_hash_file)
try:
c.perform()
except Exception as e:
print e
c.close()
def upload(self, full_filename, filesize):
self.initRange(filesize)
filename = os.path.basename(full_filename)
sys.stderr.write("filename: %s\n" % full_filename)
c = pycurl.Curl()
c.setopt(pycurl.USERNAME, self.username)
c.setopt(pycurl.PASSWORD, self.password)
c.setopt(pycurl.VERBOSE, False)
c.setopt(pycurl.DEBUGFUNCTION, self.test)
c.setopt(pycurl.NOBODY, True)
c.setopt(pycurl.HEADER, False)
ftp_file_path = os.path.join(self.server, os.path.basename(full_filename))
file_hash = get_file_hash(full_filename)
ftp_hash_file = ftp_file_path + "_%s" % file_hash
# Getting filesize if exist on server.
try:
c.setopt(pycurl.URL, ftp_file_path)
c.perform()
filesize_offset = int(c.getinfo(pycurl.CONTENT_LENGTH_DOWNLOAD))
except Exception as error_msg:
print error_msg
wx.MessageBox(str(error_msg), 'Connection error!',
wx.OK | wx.ICON_ERROR)
# Exit upload function.
return True
ftp_file_append = True
# Get ftp file hash.
self.get_ftp_file_hash(filename)
offset = filesize_offset == -1 and '0' or filesize_offset
sys.stderr.write("L_file hash : {0:.<60}: {1:<40}\n".format(filename, file_hash))
sys.stderr.write("F_file hash : {0:.<60}: {1:<40}\n".format(filename, self.ftp_filehash))
sys.stderr.write("{0:15} : {1:.>15}\n".format('filesize:', filesize))
sys.stderr.write("{0:15} : {1:.>15}\n".format('ftp_filesize', offset))
sys.stderr.write("{0:15} : {1:.>15}\n".format('to upload:', filesize - int(offset)))
# File not exist on FTP server.
if filesize_offset == -1:
# file not exist: uploading from offset zero.
ftp_file_append = False
filesize_offset = 0
# Local and FTP file size and files MD5 are the same.
elif filesize_offset == self.filesize and file_hash == self.ftp_filehash:
sys.stderr.write("--- File exist on server! ---\n\n")
self.upload_file_speed.SetLabel("File exist on server!")
self.sb_speed.SetStatusText("File exist on server!", 1)
# Check next filename.
return False
# Ftp file and local file different data.
elif file_hash != self.ftp_filehash:
ftp_file_append = False
filesize_offset = 0
ftp_hash_file_old = filename + "_" + self.ftp_filehash
# delete old hash file.
self.delete_ftp_hash_file(ftp_hash_file_old)
c.setopt(pycurl.FTPAPPEND, ftp_file_append)
c.setopt(pycurl.UPLOAD, True)
c.setopt(pycurl.PROGRESSFUNCTION, self.progress)
with open('filehash.txt', 'w') as f:
f.write(file_hash)
for item in ("filehash.txt", full_filename):
# dont show progress by default.
noprogress = True
# upload ftp_hash_file first.
ftp_url = ftp_hash_file
with open(item, "rb") as f:
# chages ftp_url and show progress values, add filesize_offset.
if item != "filehash.txt":
f.seek(filesize_offset)
noprogress = False
ftp_url = ftp_file_path
c.setopt(pycurl.URL, ftp_url)
c.setopt(pycurl.NOPROGRESS, noprogress)
c.setopt(pycurl.READFUNCTION, f.read)
try:
c.perform()
if item != "filehash.txt":
sys.stderr.write("{0:15} : {1:.>15}\n\n".format("size uploaded", int(c.getinfo(pycurl.SIZE_UPLOAD))))
except Exception as error_msg:
print error_msg
wx.MessageBox(str(error_msg), 'Connection error!',
wx.OK | wx.ICON_ERROR)
# Exit upload function.
return True
self.ftp_filehash = '0'
c.close()
if __name__ == '__main__':
pass