Basically, I have a python client to send command to ask server do somethings, I have implemented threading, but it seems not working. For example, when I send "start" command to the server, it will execute job_function, but during this time, the client is freezing. So basically, I want my server still able to respond to client's request, while executing tasks, and that's the reason I use thread.
Server.py:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 5005)) # Bind to the port
s.listen(1) # Now wait for client connection.
c, addr = s.accept() # Establish connection with client.
while True:
print('Got connection from', addr)
data = c.recv(1024).decode()
print(data)
if data == "start":
print("start the service")
c.sendall('started service'.encode())
threading.Thread(target=job_function).start()
elif data == "suspend":
print("suspend service")
c.sendall('suspended service'.encode())
else:
c.sendall('wrong command'.encode())
c.close() # Close the connection
Client.py:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',5005))
while True:
x = input("Enter command: ")
s.sendall(x.encode())
print(x)
data = s.recv(1024).decode()
print(data)
s.close()
It can also be done only using recv() function.
client side:
sssize = os.stat('fileName').st_size
file = open('fileName', 'rb')
amm = file.read(sssize)
dfd = amm
#########
c.send(bytes(str(sssize), 'utf-8'))
rrespo = c.recv(1024).decode()
######
if rrespo == 'yess':
m = 0
lenmsg = 1024
loop = (int((sssize) / lenmsg))
if (sssize)<lenmsg:
c.send(dfd[0:sssize])
else:
dddf='oksend'
for ioo in range(0, loop):
if dddf=='oksend':
c.send(dfd[ioo * lenmsg:ioo * lenmsg + lenmsg])
stloop = ioo * lenmsg + lenmsg
print(int(m / (loop - 1) * 100))
m = m + 1
dddf = c.recv(6).decode()
print(dddf, ioo)
nextloop = sssize - loop * lenmsg
if nextloop > 0:
c.send(dfd[stloop:stloop + nextloop])
file.close()
print('file transffered successfully')
Server Side:
filename = input(str("Enter file name :")
fill = open(filename, 'wb')
c.send(bytes(commm, 'utf-8'))
# sizze=c.recv(1024).decode()
# print('size')
# print(sizze)
# c.send(bytes('done', 'utf-8'))
fileSize = c.recv(1024).decode()
c.send(bytes('yess', 'utf-8'))
lenmsg=1024
loop = int(int(fileSize) / lenmsg)
if (int(fileSize))<lenmsg:
image = c.recv(int(fileSize))
fill.write(image)
else:
for i in range(0, loop):
image = c.recv(lenmsg)
fill.write(image)
print('completed downloading:', int((i / (loop - 1) * 100)), '%')
c.send(bytes('oksend', 'utf-8'))
nextloop = int(fileSize) - loop * lenmsg
if nextloop > 0:
image = c.recv(nextloop)
fill.write(image)
fill.close()
print('file downloaded successfully')
Related
I'm trying to build a fake money transfer program with sockets in python. Everything is working perfectly except the "name" and "amount" transfer from the server to the client. When someone clicks receive on the client interface, the server is supposed to send the client the name of the person who sent the money and the amount. The problem is that the client is not receiving the data sent from the server. When you click the "receive" button, the interface just freezes then crashes. From the debugging I've done, I'm pretty sure the server is sending the name and amount, but the client is not receiving it. I honestly have no idea why it's not working. Everything I did should work like it has numerous other times throughout the program. This one has got me stumped.
Any help would be great. Thanks! đ
[CODE]
Server.py:
import socket
import threading
HOST = '192.168.1.6'
PORT = 9090
def client_fun(client, addr):
global transfers
print(f"{addr} just connected!")
connected = True
while connected:
msg = client.recv(1024).decode('utf-8')
if msg == "RECEIVE_CHECK":
usrn = client.recv(1024).decode('utf-8')
transfers_ = open("transfers.txt", "r")
transfers = str(transfers_.readlines())
transfers = transfers.split("+")
transfers[0] = transfers[0].replace("[", "")
transfers[0] = transfers[0].replace("'", "")
transfers.pop()
names = []
for tran in transfers:
tran_ = tran.split("-")
i = 0
while i <= len(tran):
names.append(tran_[2])
i += 1
if usrn in names:
client.send("OK".encode('utf-8'))
else:
client.send("NO".encode('utf-8'))
if usrn in names:
for tran in transfers:
tran_ = tran.split("-")
if usrn == tran_[2]:
name = str(tran_[0])
amount = str(tran_[1])
client.send(name.encode('utf-8'))
client.send(amount.encode('utf-8'))
account_file = usrn + "_" + "account.txt"
account_r = open(account_file, "r")
account_r = str(account_r.readlines())
account_r = account_r.replace(']', '')
account_r = account_r.replace('[', '')
account_r = account_r.replace("'", "")
try:
account_r = int(account_r)
except:
print("Can't Convert Str to Int!")
break
new_amount = int(tran_[1]) + account_r
account_w = open(account_file, "w")
account_w.write(str(new_amount))
account_w.close()
tran = tran + "+"
transFers_ = open("transfers.txt", "r")
transFers = str(transFers_.readlines())
transFers_.close()
transFers = transFers.replace(']', '')
transFers = transFers.replace('[', '')
transFers = transFers.replace("'", "")
transFers = transFers.replace(tran, '')
transFers_ = open("transfers.txt", 'w+')
transFers_.write(transFers)
transFers_.close()
print("Excepted!")
else:
print("Nothing Here!")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
print("Server is listening!")
while True:
c_socket, address = server.accept()
thread = threading.Thread(target=client_fun, args=(c_socket, address))
thread.start()
Client.py:
import socket
HOST = '192.168.1.6'
PORT = 9090
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def receive(usrn):
socket.send("RECEIVE_CHECK".encode('utf-8'))
socket.send(usrn.encode('utf-8'))
c = socket.recv(1024).decode('utf-8')
if c == "OK":
try:
print("Trying to except....")
name = socket.recv(2000).decode('utf-8')
amount = socket.recv(2000).decode('utf-8')
print("Excepted!")
messagebox.showwarning("Continue?", f"{name} has sent you ${amount}", icon="question")
messagebox.showwarning("Info", f"${amount} has just been transferred to your account!", icon="info")
menu(usrn)
except:
print("Error!")
else:
print("Nothing Today!")
Whenever the client disconnect, the server will close itself. How can i make the server to run forever ?
What i'm doing
The server let one client to retrieve files with no issues. But the problem is when the client close the program, the server will also closed itself and wouldn't let another client to establish the connection . I had read a few articles about using while loops to make the session alive. Does anyone know how can I do that ?
Server.py
import socket, os, subprocess, shutil, pickle, struct
# 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)
except socket.error as msg:
bind_socket()
# send file list
def flist(conn):
try:
arr = pickle.dumps(os.listdir())
conn.send(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'))
# Establish connection with a client (socket must be listening)
def socket_accept():
conn, address = s.accept()
main(conn)
conn.close()
create_socket()
bind_socket()
socket_accept()
You should put accept in the loop, and you may need use a thread to handle read
sample code:
def handle_read(s):
while True:
data = s.recv(1024)
if not data:
#When the client closed, recv will return an empty data
s.close()
break
data = data.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 = handle_read, args=(conn, ))
t.start()
I wrote a script in Python 3.8.6 to send and receive files between different devices. I am sending and receiving files normally, the problem happens when I receive multiple simultaneous connections from different devices.
I configured the script to save the files in folders named with the address of the device that sends the file and what is happening is that when several devices send files at the same time, files from one device go to another folder, randomly. The files are mixed.
I have an idea of why it is happening but not how to solve it.
I thought as an alternative to receive only one connection at a time.
But I don't know how to do this.
sendfile.py
def conectividade(host="192.168.0.13", porta=1218, timeout=5):
while True:
try:
socket.setdefaulttimeout(timeout)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, porta))
return True
except Exception:
return False
# Function that sends the collected data.
def coleta():
total = []
conectividade()
conect = conectividade()
if conect == False:
print("\nConnectivity is",conect)
pass
else:
data_hoje = datetime.now().strftime('%Y-%b-%d')
direct = f".\\{data_hoje}\\"
arquivos = os.listdir(direct)
for arquivo in arquivos:
try:
sock = socket.socket()
host = "192.168.0.13"
porta = 1218
print("Connectivity is", conect)
sock.connect((host, porta))
total += arquivo.split(',')
sock.send(str.encode(arquivo))
arquivo = str.encode(direct + arquivo)
with open(arquivo, "rb") as file:
data = file.read(1024)
resposta = sock.recv(1024)
if resposta == b'Waiting file':
file_size = os.path.getsize(arquivo)
print(b"sending " + arquivo)
print(file_size,"kb")
sock.send(bytes(str(file_size),'utf-8'))
resposta = sock.recv(1024)
if resposta == b'Waiting...':
while data:
sock.send(data)
data = file.read(1024)
if not data:
print(f"**Sending Complete**\n")
sock.close()
# Delete files after uploads
if total == arquivos:
print(f"Uploaded files:\n",total)
except socket.error:
print("\nSocket Error\n")
receive.py
data_hoje = datetime.now().strftime('%Y-%b-%d')
sock = socket.socket()
host ='192.168.0.13'
porta = 1218
sock.bind((host, porta))
sock.listen(10)
total = []
while True:
conn, addr = sock.accept()
pasta = ".\\" + addr[0].replace('.','_')
subpasta = pasta + "\\" + data_hoje
if os.path.exists(pasta) == False:
os.makedirs(f'{pasta}')
if os.path.exists(subpasta) == False:
os.makedirs(f'{subpasta}')
data = conn.recv(1024)
while data == b'':
conn.close()
conn, addr = sock.accept()
data = conn.recv(1024)
if data == b'Finalizando socket':
print("Finalizando conexĂŁo com " + addr[0])
conn.close()
sock.close()
total += data.decode().split(',')
name_file = total[-1]
with open(f"{subpasta}\\{name_file}", "wb") as file:
conn.send(b"Waiting file")
data = conn.recv(1024)
tamanho = data.decode('utf-8')
file_size = int(tamanho)
if file_size != 0:
conn.send(b"Waiting...")
print("HOST <--> " + addr[0] + f" Download de {name_file} - {tamanho} kb")
while data:
data = conn.recv(1024)
file.write(data)
conn.close()
In receive.py you have:
conn, addr = sock.accept()
# [...]
while data == b'':
conn.close()
conn, addr = sock.accept()
data = conn.recv(1024)
The client that connects on the first accept() may be different from the client that connects on the accept() inside the cycle, which could lead to the files mixing up as you described. You should re-write it with a single accept(), to guarantee the whole processing is done for the same client. This approach is described in TCP/IP Client and Server - PyMOTW-3.
Modified receive.py:
data_hoje = datetime.now().strftime("%Y-%b-%d")
sock = socket.socket()
host = "192.168.0.13"
porta = 1218
sock.bind((host, porta))
sock.listen(10)
total = []
try:
while True:
conn, addr = sock.accept()
try:
pasta = ".\\" + addr[0].replace(".", "_")
subpasta = pasta + "\\" + data_hoje
if os.path.exists(pasta) is False:
os.makedirs(f"{pasta}")
if os.path.exists(subpasta) is False:
os.makedirs(f"{subpasta}")
data = b""
while data == b'':
data = conn.recv(1024)
if data == b"Finalizando socket":
print("Finalizando conexĂŁo com " + addr[0])
continue
total += data.decode().split(",")
name_file = total[-1]
with open(f"{subpasta}\\{name_file}", "wb") as file:
conn.send(b"Waiting file")
data = conn.recv(1024)
tamanho = data.decode("utf-8")
file_size = int(tamanho)
if file_size != 0:
conn.send(b"Waiting...")
print(
"HOST <--> " + addr[0] + f" Download de {name_file} - {tamanho} kb"
)
while data:
data = conn.recv(1024)
file.write(data)
finally:
conn.close()
finally:
sock.close()
Basically, what was causing the error was the conectividade() function recursively in the original script.
so I needed...
while True:
conn.close()
conn, addr = socket.accept()
data = conn.recv
What caused the files to mix, as said by fzdb ...
How was the new script ...
sendfile.py
import socket
import os
from datetime import datetime
def coleta():
total = []
data_hoje = datetime.now().strftime('%Y-%b-%d')
direct = f".\\{data_hoje}\\"
arquivos = os.listdir(direct)
for arquivo in arquivos:
try:
sock = socket.socket()
host = "192.168.0.13"
porta = 1218
print("Connectivity is",)# conect)
sock.connect((host, porta))
total += arquivo.split(',')
sock.send(str.encode(arquivo))
arquivo = str.encode(direct + arquivo)
with open(arquivo, "rb") as file:
data = file.read(1024)
resposta = sock.recv(1024)
if resposta == b'Waiting file':
file_size = os.path.getsize(arquivo)
print(b"sending " + arquivo)
print(file_size,"kb")
sock.send(bytes(str(file_size),'utf-8'))
resposta = sock.recv(1024)
if resposta == b'Waiting...':
while data:
sock.send(data)
data = file.read(1024)
if not data:
sock.close()
print(f"**Sending Complete**\n")
if total == arquivos:
print(f"Uploaded files:\n",total)
except socket.error:
print("\nSocket Error\n")
receive.py
import socket
import os
from datetime import datetime
data_hoje = datetime.now().strftime('%Y-%b-%d')
host ='192.168.0.13'
porta = 1218
sock.bind((host, porta))
sock.listen(10)
total = []
while True:
conn, addr = sock.accept()
pasta = ".\\" + addr[0].replace('.','_')
subpasta = pasta + "\\" + data_hoje
if os.path.exists(pasta) == False:
os.makedirs(f'{pasta}')
if os.path.exists(subpasta) == False:
os.makedirs(f'{subpasta}')
data = conn.recv(1024)
if data == b'':
conn.close()
total += data.decode().split(',')
name_file = total[-1]
try:
with open(f"{subpasta}\\{name_file}", "wb") as file:
conn.send(b"Waiting file")
data = conn.recv(1024)
tamanho = data.decode('utf-8')
file_size = int(tamanho)
if file_size != 0:
conn.send(b"Waiting...")
print("HOST <--> " + addr[0] + f" Download de {name_file} - {tamanho} bytes")
while data:
data = conn.recv(1024)
file.write(data)
except:
pass
Thank you!
For those who want to help with the original code ...
I have problems with NumPad on pynput
https://github.com/gconelhero/Keylogger
I'm trying to send files from server to client with the code here and doesn't succeed, the client gets stuck on the last recv. Server is done sending all the times. I've tried many things to try to solve:
sending 'STOP' when server is done sending -> client somehow receives the last bytes with 'STOP' and writes it to the file(even though they were different client.send() the client mixed it)
Sending how many bytes am I going to receive and then sending the bytes
Sending a pickle of [bytes, 'OK'/'STOP']
Server.py
host = '0.0.0.0'
port = 9898
s = socket.socket()
s.bind((host, port))
s.listen(1)
client, addr = s.accept()
def download_file(self, file_name, client):
with open(file_name, 'rb') as f:
file_name_without_path = file_name.split('\\')
file_name_without_path = file_name_without_path[len(file_name_without_path) - 1]
filesize = os.path.getsize(file_name)
client.send(pickle.dumps([file_name_without_path, filesize])) # send name and size of file
bytesToSend = f.read(1024)
client.send(bytesToSend)
print(bytesToSend)
bytes_sent = 0
while len(bytesToSend) != 0:
bytesToSend = f.read(1024)
bytes_sent += len(bytesToSend)
client.send(bytesToSend)
print(bytesToSend)
print('done')
Client.py
s = socket()
PORT = 9898
s.connect(('127.0.0.1', PORT))
def download(self, path):
filename, filesize = pickle.loads(s.recv(1024))
new_file_path = path + '\\' + filename
f = open(new_file_path, 'wb')
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while data != ''.encode():
print('before')
data = s.recv(1024)
print(data)
print('after')
totalRecv += len(data)
percetage = (totalRecv / filesize) * 100
print(str((totalRecv / filesize) * 100) + "%")
f.write(data)
if percetage >= 100:
break
f.close()
print('done')
I am pretty new to python and I had a script idea:
You have a listener which is waiting for functions and a client script which sends instructions to the server and in this case instructions are functions.
Like that I could execute functions code from the client on the other computer
I tried pickle but I can't figure out if it's working with functions
Shall I use Sockets or something else ?
here is the server code:
import socket
import time
HEADER_LENGHT = 10
IP = socket.gethostname()
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((IP, PORT))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established ! ")
while True:
full_msg = b''
new_msg = True
while True:
msg = s.recv(16)
if new_msg:
print(f"New message lenght: {msg[:HEADERSIZE]}")
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg
if len(full_msg)- HEADERSIZE == msglen:
print("full msg recvd")
print(full_msg[HEADERSIZE:])
d = pickle.loads(full_msg[HEADERSIZE:])
print(d)
new_msg = True
full_msg = b''
print(full_msg)
The client code :
import socket
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1235))
while True:
full_msg = b''
new_msg = True
while True:
msg = s.recv(16)
if new_msg:
print(f"New message lenght: {msg[:HEADERSIZE]}")
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg.decode("utf-8")
if len(full_msg)- HEADERSIZE == msglen:
print("full msg recvd")
print(full_msg[HEADERSIZE:])
new_msg = True
full_msg = b''
print(full_msg)
Here is the function code:
def generate(target, apikey, nbfriendly, nbteacher, nbleader, accounts):
acc_list = accounts
jsonFile = open("config.json", "r")
data = json.load(jsonFile)
lines_count = 0
if nbfriendly == "":
nbfriendly = 10
if nbteacher == "":
nbteacher = 10
if nbleader == "":
nbleader = 10
if apikey == "":
apikey = (data['steamWebAPIKey'])
if target == "":
target = (data['target'])
for l in accounts:
lines_count = lines_count + 1
conn = sqlite3.connect("accounts.sqlite")
c = conn.cursor()
max = accounts.count("\n")
counter = 0
print(accounts)
accounts = accounts.replace(":", " ")
accounts = accounts.replace("\n", " ")
accounts.split()
print(accounts)
splitted = accounts.split()
while counter < max:
username = splitted[counter]
password = splitted[(counter + 1)]
c.execute(
"INSERT INTO accounts (username, password, sharedSecret, lastCommend, operational) VALUES (? , ?, ?, ? , ?)",
(username, password, blank, mone, one)
)
conn.commit()
counter += 2
nbfriendly = int(nbfriendly)
nbteacher = int(nbteacher)
nbleader = int(nbleader)
target = str(target)
(data['commend']['friendly']) = nbfriendly
(data['commend']['teaching']) = nbteacher
(data['commend']['leader']) = nbleader
(data['target']) = target
(data['steamWebAPIKey']) = apikey
data = json.dumps(data, indent=4)
jsonFile.close()
with open('config.json', 'w') as outfile:
outfile.write(data)
outfile.close()
I'm not sure your code for sending messages using socket is correct (I don't see where you're sending bytes).
Concerning pickle is is indeed possible to use it as a function. Plus, the good thing is that it is dumped as a bytes object, so you don't even need to cast it before sendding it with sockets.
On the client side:
import pickle
def f(n):
return n * f(n - 1) if n else 1
to_send = pickle.dumps(f)
# Send to_send using sockets then
Then, on the server side, the only thing you need is to load the function:
import pickle
f = pickle.loads(received)
Since everything is an object in Python, you can use the exact same method to send the function's arguments using sockets and pickle.