I am trying to make an application which is accessible for a wide range of users.
Its some basic socket + python networking stuff.
I researched a bit recently and I tried a few things.
I implemented some UPNP stuff via miniupnpc but the thing is that you need a permission to use UPNP on most routers which is not ideal for my needs. I am trying to completely bypass things like port forwarding.
I also tried to completely switch from Python socket to pyp2p but I could't get it working because of the lack of documentation and maintenance on the project.
Is there an easy way to bypass NAT and if yes how ?
Client:
import socket
import struct
import os
import pickle
from pygame import mixer
def connect(host, port):
ourmusic = []
fileBRAIN = []
musicPath = './music'
s = socket.socket()
print('created socket')
s.connect((host,port))
print('conected to ',host)
#identify self
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
IPAddrBYTE = str(IPAddr).encode('utf-8')
send_msg(s, IPAddrBYTE)
if os.path.exists(str(host)) == True :
print('server seen previously')
#load host's song list
fileBRAIN = pickle.load(open( str(host), 'rb'))
#recieve new files from host
receiveFiles(s, fileBRAIN)
#compare files
saveMusicList(ourmusic, musicPath)
filesToTransmit = diff(ourmusic, fileBRAIN)
#transmit music which host dont have
transmitFiles(s , filesToTransmit, fileBRAIN)
#save host's song list
pickle.dump(fileBRAIN, open(str(host), 'wb'))
#start playing music
clientMainLoop(s)
else:
print('server not seen previously')
#recieve music files from host
receiveFiles(s, fileBRAIN)
#compare files
saveMusicList(ourmusic, musicPath)
filesToTransmit = diff(ourmusic, fileBRAIN)
#transmit music which host dont have
transmitFiles(s , filesToTransmit, fileBRAIN)
#save host's song list
pickle.dump(fileBRAIN, open(str(host), 'wb'))
#start playing music
clientMainLoop(s)
def clientMainLoop(socket):
mixer.init()
while True:
randomsongBYTE = recv_msg(socket)
randomsong = randomsongBYTE.decode('utf-8')
mixer.music.load('./music/' + randomsong)
mixer.music.play()
print('now playing: ' + randomsong)
while mixer.music.get_busy() == True:
temp = 0
else:
print('music ended receiving next...')
def transmitFiles(socket, files, fileBRAIN):
Transmissions = struct.pack('i',len(files))
send_msg(socket, Transmissions)
for x in files:
filename = str(x).encode('utf-8')
send_msg(socket, filename)
file = open('./music/' + x , 'rb')
file_data = file.read()
send_msg(socket, file_data)
fileBRAIN.append(str(x))
print(x + '\n' + 'has been send transmitted successfully')
print('')
def receiveFiles(s, fileBRAIN):
i = 1
transmissionsDATA = recv_msg(s)
transmissionsTUP = struct.unpack('i',transmissionsDATA)
transmissions = transmissionsTUP[0]
print('there are ' + str(transmissions) + ' awaiting receive
transmissions')
while i <= transmissions:
BYTEfilename = recv_msg(s)
filename = BYTEfilename.decode('utf-8')
file = open('./music/' + filename, 'wb')
file_data = recv_msg(s)
file.write(file_data)
file.close()
fileBRAIN.append(str(filename))
print('transmission ' + str(i) + ' recieived')
i = i + 1
def saveMusicList(musiclist, musicPath):
for entry in os.listdir(musicPath):
if os.path.isfile(os.path.join(musicPath, entry)):
musiclist.append(entry)
#find elements which are not in the other list
def diff(li1, li2):
return (list(set(li1) - set(li2)))
#TCP msg protocoll
def send_msg(sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
Server :
import socket
import os
import struct
import pickle
import miniupnpc
from random import randint
from pygame import mixer
def init(port):
fileBRAIN = []
ourmusic = []
files = []
musicPath = './music'
try:
#Network Gateway (port forwarding)
upnp = miniupnpc.UPnP()
upnp.discoverdelay = 10
upnp.discover()
upnp.selectigd()
upnp.addportmapping(port, 'TCP', upnp.lanaddr, port,
'OpenMCS', '')
except:
print('INFO:Port is already forwarded or you dont have the
premission to forward it')
s = socket.socket()
host = ('') #socket.gethostname()
s.bind((host,port))
s.listen(5)
print(host)
print('waiting for any incoming conections ... ')
conn,addr = s.accept()
#get client identity
ClientIPAddrBYTE = recv_msg(conn)
ClientIPAddr = ClientIPAddrBYTE.decode('utf-8')
if os.path.exists(ClientIPAddr) == True :
print('client seen previously')
#load client's song list
fileBRAIN = pickle.load(open( ClientIPAddr, 'rb'))
#compare files
saveMusicList(ourmusic, musicPath)
filesToTransmit = diff(ourmusic, fileBRAIN)
#transmit new files client doesn't have
transmitFiles(conn, filesToTransmit, fileBRAIN)
#recieve music files we dont have
receiveFiles(conn, fileBRAIN)
#save client's song list
pickle.dump(fileBRAIN, open(ClientIPAddr, 'wb'))
#start playing music
serverMainLoop(conn, ourmusic, musicPath)
else:
print('client not seen previously')
#transmit own music files to client
transmitFiles(conn, files, fileBRAIN)
#recieve music files we dont have
receiveFiles(conn, fileBRAIN)
#save client's song list
pickle.dump(fileBRAIN, open(ClientIPAddr, 'wb'))
#start playing music
serverMainLoop(conn, ourmusic, musicPath)
def serverMainLoop(socket, ourmusic, musicPath):
saveMusicList(ourmusic, musicPath)
mixer.init()
while True:
randomsong = ourmusic[randint(0, (len(ourmusic) - 1 ))]
randomsongBYTE = randomsong.encode('utf-8')
send_msg(socket, randomsongBYTE)
mixer.music.load('./music/' + randomsong)
mixer.music.play()
print('now playing: ' + randomsong)
while mixer.music.get_busy() == True:
temp = 0
else:
print('music ended picking next...')
def transmitFiles(socket, files, fileBRAIN):
Transmissions = struct.pack('i',len(files))
send_msg(socket, Transmissions)
for x in files:
filename = str(x).encode('utf-8')
send_msg(socket, filename)
file = open('./music/' + x , 'rb')
file_data = file.read()
send_msg(socket, file_data)
fileBRAIN.append(str(x))
print(x + '\n' + 'has been send transmitted successfully')
print('')
def receiveFiles(s, fileBRAIN):
i = 1
transmissionsDATA = recv_msg(s)
transmissionsTUP = struct.unpack('i',transmissionsDATA)
transmissions = transmissionsTUP[0]
print('there are ' + str(transmissions) + ' awaiting receive
transmissions')
while i <= transmissions:
BYTEfilename = recv_msg(s)
filename = BYTEfilename.decode('utf-8')
file = open('./music/' + filename, 'wb')
file_data = recv_msg(s)
file.write(file_data)
file.close()
fileBRAIN.append(str(filename))
print('transmission ' + str(i) + ' recieved')
i = i + 1
def saveMusicList(musiclist, musicPath):
for entry in os.listdir(musicPath):
if os.path.isfile(os.path.join(musicPath, entry)):
musiclist.append(entry)
#find elements which are not in the other list
def diff(li1, li2):
return (list(set(li1) - set(li2)))
#TCP msg proctocoll
def send_msg(sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
You can find the full code here if you need it : https://github.com/Finn1510/OpenMCS
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!")
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 types in fup in the terminal, the program will ask for filename and the file will be uploaded 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 seems like not working. When I browse and upload a file, the server does not receive any new file. I am stuck 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
from tkinter import filedialog
from tkinter import *
import time, shutil
root = Tk()
# 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 = filedialog.askopenfilename(parent=root, initialdir="/", title='Please select a directory')
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):
fup(conn)
def run():
mano(host, s)
upload_button = Button(root, text="upload", command=run)
upload_button.place(x=130, y=17, width=50, height=22)
root.mainloop()
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()
**After I click on upload and it show uploaded compelte, but the server doesn't receive any new file.
Since you have used filedialog.askopenfilename() to get the filename which is a full pathname, like for example C:/Users/heng/PycharmProjects/testtest/New System/test.txt. So the server gets the same full pathname and try to create the output file. But it will fail if C:/Users/heng/PycharmProjects/testtest/New System/ does not exists in server side.
To fix the issue, either sending the filename part (without the directory information) in client side:
def fup(conn):
try:
filename = filedialog.askopenfilename(parent=root, initialdir="/", title='Please select a directory')
if os.path.isfile(filename):
_, basename = os.path.split(filename)
conn.send(str("fup~" + basename).encode("utf-8")) # use basename instead of filename
...
or remove the directory information in server side:
def fdown(fullname, conn): # renamed filename to fullname
_, filename = os.path.split(fullname) # get the filename part only
try:
...
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.
I have a code which is running on 2 hosts. They are processing some photos. When host1 receives a message, it will send some of its photos to host2 for processing. It will also send a list to host2 (it will convert it to string and then it will send it).
import pickle
import time, threading
host = commands.getoutput("hostname -I")
port = 5005
i = 0
backlog = 5
BUFSIZE = 4096
queueList = []
start = []
end = []
l = threading.Lock()
def read_udp(s):
data,addr = s.recvfrom(1024)
global start
if data.startswith('10.0.0'):
print("received message:", data)
data_split = data.split(" ")
address = data_split[0]
num = int(data_split[1])
ipToTransfer = address
l.acquire()
transferList = queueList[-num:]
del queueList[-num:]
transferStart = start[-num:]
del start[-num:]
l.release()
msg = pickle.dumps(transferStart)
#udp_send('New Transfer', ipToTransfer)
udp_send(msg, ipToTransfer)
send_file(ipToTransfer, transferList)
else:
recvStart = pickle.loads(data)
print("start before add::: ", start)
print("received::: ", recvStart)
l.acquire()
start = start + recvStart
l.release()
print("start after add::: ", start)
def udp_send(s, ip):
UDP_IP = ip
if(type(s) == str):
MESSAGE = s
else:
MESSAGE = pickle.dumps(s)
#print(MESSAGE)
print ("UDP target IP & port:", UDP_IP, port)
print ("message:", MESSAGE)
sock3 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock3.sendto(MESSAGE, (UDP_IP, port))
class Receiver:
''' Buffer binary data from socket conn '''
def __init__(self, conn):
self.conn = conn
self.buff = bytearray()
def get(self, size):
''' Get size bytes from the buffer, reading
from conn when necessary
'''
while len(self.buff) < size:
data = self.conn.recv(BUFSIZE)
if not data:
break
self.buff.extend(data)
# Extract the desired bytes
result = self.buff[:size]
# and remove them from the buffer
del self.buff[:size]
return bytes(result)
def save(self, fname):
''' Save the remaining bytes to file fname '''
with open(fname, 'wb') as f:
if self.buff:
f.write(bytes(self.buff))
while True:
data = self.conn.recv(BUFSIZE)
if not data:
break
f.write(data)
def send(sock2, data2):
while data2:
sent = sock2.send(data2)
data2 = data2[sent:]
def send_file(ipToTransfer, transferList):
while transferList:
fname = transferList.pop(0)
print("transferring:", fname)
with open(fname, 'rb') as f:
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock2.connect((ipToTransfer, 5005))
except socket.error as err:
print(err, ipToTransfer, 5005)
sock2.close()
return
# Send the file name length & the filename itself in one packet
send(sock2, pack('B', len(fname)) + fname.encode())
while True:
data2 = f.read(BUFSIZE)
if not data2:
break
send(sock2, data2)
sock2.close()
When host2 receives this string, it will convert it to list again, but I receive an EOFError in this part. My cmd doesn't have the copy capability, so I upload the photo from this error:
What's wrong?
you delete the pointer to what is being pickled
transferStart = start[-num:]
del start[-num:]
l.release()
msg = pickle.dumps(transferStart)
If you are trying to remove elements from a list that is not the way to do it. Consider popping or reassigning into another list that does not have that element, etc.