I am new to python and finding it really difficult trying to understand how to send files using sockets with a tcp connection i found this code in another question that seems to be useful
Client Side
def _sendFile(self, path):
sendfile = open(path, 'rb')
data = sendfile.read()
self._con.sendall(encode_length(len(data))) # Send the length as a fixed size message
self._con.sendall(data)
# Get Acknowledgement
self._con.recv(1) # Just 1 byte
Server Side
def _recieveFile(self, path):
LENGTH_SIZE = 4 # length is a 4 byte int.
# Recieve the file from the client
writefile = open(path, 'wb')
length = decode_length(self.con.read(LENGTH_SIZE) # Read a fixed length integer, 2 or 4 bytes
while (length):
rec = self.con.recv(min(1024, length))
writefile.write(rec)
length -= sizeof(rec)
self.con.send(b'A') # single character A to prevent issues with buffering
Now i have two problems with this code First
self._con.sendall(encode_length(len(data)))
in this line it gives me an error saying encode_length is undefined
Secondly these are functions that send and receive file Where do i call them Do i first form a TCP Connection and then call these functions And how exactly to call them , if i call them directly it gives me an error on client side saying _sendFile(self, path) takes two arguments (since i am not passing self just the path)
Thirdly i am using function from os library to get complete path , So i am calling the function like
_sendFile(os.path.abspath("file_1.txt"))
is this the correct way to pass the argument
Sorry i know this question is pretty basic and lame but everywhere online i can basically get the function but not how to call it
right now this is how i am calling the function
serverIP = '192.168.0.102'
serverPort = 21000
clientSocket = socket(AF_INET, SOCK_STREAM)
message = "Want to Backup a Directory"
clientSocket.connect((serverIP, serverPort))
_sendFile(os.path.abspath("file_1.txt"))
Which is basically wrong
I am using the same computer for both Client and Server
Running Python on Ubuntu using terminal
It's because you simply haven't defined functions encode/decode_lenght
.
Your function is: def _sendFile(self, path): ...
.
Do you know how to use self
? It is used in the classes. So define it without self
, or use classes:
from socket import *
class Client(object):
def __init__(self):
self.clientSocket = socket(AF_INET, SOCK_STREAM)
def connect(self, addr):
self.clientSocket.connect(addr)
def _sendFile(self, path):
sendfile = open(path, 'rb')
data = sendfile.read()
self._con.sendall(encode_length(len(data))) # Send the length as a fixed size message
self._con.sendall(data)
# Get Acknowledgement
self._con.recv(1) # Just 1 byte
>>> client = Client()
>>> client.connect(("192.168.0.102", 21000))
>>> client._sendFile(os.path.abspath("file_1.txt")) # If this file is in your current directory, you may just use "file_1.txt"
And same (almost) for Server
.
Where to define these functions? In the code ofcorse! What should your functions do?
OK, an example:
def encode_length(l):
#Make it 4 bytes long
l = str(l)
while len(l) < 4:
l = "0"+l
return l
# Example of using
>>> encode_length(4)
'0004'
>>> encode_length(44)
'0044'
>>> encode_length(444)
'0444'
>>> encode_length(4444)
'4444'
Just a little bit:
self
redirects to your current object, ex:
class someclass:
def __init__(self):
self.var = 10
def get(self):
return self.var
>>> c = someclass()
>>> c.get()
10
>>> c.var = 20
>>> c.get()
20
>>> someclass.get(c)
20
>>>
How does someclass.get(c)
work?
While executing someclass.get(c)
, we are not creating an new instance of someclass
.
When we call .get()
from an someclass
instance, it automaticly sets self
to our instance object. So someclass.get(c)
== c.get()
And if we try to do someclass.get()
, self
was not defined, so it will raise an error:
TypeError: unbound method get() must be called with someclass instance as first argument (got nothing instead)
You can use decorator to call functions of a class (not its instance!):
class someclass:
def __init__(self):
self.var = 10
def get(self):
return 10 # Raises an error
@classmethod
def get2(self):
return 10 # Returns 10!
Sorry for my bad explanations, my English is not perfect
Here are some links: