python- how to send file to different network using socket - python

morning sensei, im learning network programming using socket now. i have able to transfer file from my laptop to my smartphone in the some network using public ip. however if im trying to transfer it to other phone in different network it doesnt work and the phone cant connect.
here is my server.py:
import sys
import socket
import os
host = ''
skServer = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
skServer.bind((host,2525))
skServer.listen(10)
print ("Server Active")
bFileFound = 0
while True:
Content,Address = skServer.accept()
print (Address, "connected")
FileName = Content.recv(8192)
sFileName = FileName.decode('utf-8')
for file in os.listdir("files/"):
if file == sFileName:
bFileFound = 1
break
if bFileFound == 0:
print (sFileName+" Not Found On Server")
else:
print (sFileName," File Found")
fUploadFile = open("files/"+sFileName,"rb+")
sRead = fUploadFile.read(8192)
while sRead:
Content.sendall(sRead)
sRead = fUploadFile.read(8192)
print ("Sending Completed")
Content.close()
skServer.close()
and here is my client.py:
import sys
import socket
skClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
skClient.connect(("<ip public>",2525))
sFileName = input("Enter Filename to download from server : ")
sData = "Temp"
while True:
skClient.sendall(sFileName.encode('utf-8'))
sData = skClient.recv(8192)
fDownloadFile = open("storage/emulated/0/qpython"+sFileName,"wb+")
while sData:
fDownloadFile.write(sData)
sData = skClient.recv(8192)
print ("Download Completed")
skClient.close()
is there any way i can use my script globally so any network can access it?

Possibly. Some providers restrict certain types of network traffic.
You have several alternatives, one of which is to have a common VPN connection available to both devices. This technology will encapsulate your program's traffic, so the program should work the way you wish.

Related

Can connect to a socket on my local network but not on separate ones (python sockets)

I've been trying to make a program that would allow me to remote into my computer. It works perfectly when both computers are connected to the same network, and I am able to access a sort of command line that I have coded.
I am very inexperienced with networks and I'm not entirely sure what sort of information is needed.
This is the code I used:
Server:
import sys
import socket
def create_socket():
try:
global host
global port
global s
host = ""
port = 9999
s = socket.socket()
except socket.error as msg:
print("SocketCreationError: " +str(msg))
def bind_socket():
try:
global host
global port
global s
print("binding the port " + str(port)+"...")
s.bind((host,port))
s.listen(5)
except socket.error as msg:
print("SocketBindingError: " + str(msg))
print("retrying...")
bind_socket()
def socket_accept():
conn,address = s.accept()
print("Connection established. \nIP:"+address[0]+"\nPort:"+str(address[1]))
print(str(conn.recv(1024), "utf-8"), end="")
send_command(conn)
conn.close()
#allows user to send command to client computer
def send_command(conn):
while True:
try:
cmd = input(">")
if cmd == 'exit':
conn.close()
s.close()
sys.exit()
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
clientResponse = str(conn.recv(1024),"utf-8")
print(clientResponse, end="")
except Exception:
print("Something went wrong...")
def main():
create_socket()
bind_socket()
socket_accept()
main()
Client:
import socket
import os
import subprocess
#connect to socket and send cwd
s = socket.socket()
host = 'myIP'
port = 9999
s.connect((host, port))
s.send(str.encode(os.getcwd()))
#allows form of command line on host pc
while True:
try:
data = s.recv(1024)
outputStr = ""
if data.decode("utf-8") == 'dir':
dirList = os.listdir(os.getcwd())
for i in dirList:
print(i)
outputStr = outputStr + i + "\n"
elif data[:2].decode("utf-8") == 'cd':
dirTo = data[3:].decode("utf-8")
print(data[3:].decode("utf-8"))
os.chdir(os.getcwd() + "\\" + dirTo)
elif len(data) > 0:
cmd = subprocess.Popen(data.decode("utf-8"), shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE, stderr=subprocess.PIPE)
outputByte = cmd.stdout.read() + cmd.stderr.read()
outputStr = str(outputByte, "utf-8")
print(outputStr)
cwd = os.getcwd()
s.send(str.encode(outputStr +"\n"+cwd))
#handle something going wrong and just allows to continue
except Exception:
cwd = os.getcwd()
s.send(str.encode("Something went wrong...\n"+ cwd))
I am using ipv4 addresses. I think it may have something to do with port forwarding on the server side, but again I am not sure?
Thank you for any answers in advance :)
You can't connect to your computer using a remote network because of port forwarding. If you dont know what that is, I recommend taking a look at the Wikipedia article on it: https://en.wikipedia.org/wiki/Port_forwarding
There are many different methods to perform Port Forwarding, the simplest of which is the UPnP/IGD (look it up), but if you're just interested in being able to Access your computer remotely, you could just use an SSH (Secure Shell Connection) to do just this (I think it Works on remote networks as well). If you're using Linux this should be pretty easy to set up, just look up how to do it. Good luck!

How to send file from Client to Server and save it with same filename?

I'm trying to send file from client to server in python. It is sending without any problem but I want to save that received file with same file name. I'm not getting idea how to save that file with same file name as it is sent from Client to Server.The code I've wrote for this is :
Client Code
import socket, os, shutil
from stat import ST_SIZE
HOST=raw_input("Please enter IP-address : ")
PORT=int(raw_input("Please enter PORT Number : "))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
if s.recv(8)!='READY':
raw_input('Unable to connect \n\n Press any key to exit ...')
s.close()
exit()
path=raw_input("Please enter the complete PATH of your file : ")
f=open(path,'rb')
fsize=os.stat(f.name)[ST_SIZE]
s.sendall(str(fsize).zfill(8))
sfile = s.makefile("wb")
shutil.copyfileobj(f, sfile)
sfile.close()
s.close()
f.close()
Server Code
import socket
import shutil
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = ''
PORT = 23240
s.bind((HOST, PORT))
s.listen(3)
conn, addr = s.accept()
print 'conn at address',addr
conn.sendall('READY')
i=1
f = open(r'file_'+ str(i)+".txt",'wb')
i=i+1
print 'File size',fsize
sfile = conn.makefile("rb")
shutil.copyfileobj(sfile, f)
sfile.close()
f.write(conn.recv(fsize))
f.close()
conn.close()
s.close()
Your code is not very robust. recv(cnt) delivers up to cnt bytes of data, or less. So it's not sure, you read the whole file. It is even not sure, you get the "READY" in one recv. Instead, you have to use something like that:
def recv_all(sock, bufsize):
result = ''
while bufsize>0:
data = sock.recv(min(bufsize, 4096))
if not data:
raise IOError("Socket closed")
result += data
bufsize -= len(data)
return result
If you want to know the filename at the server, you also have to transfer it to the server, too. By the way, "READY" has 5 characters, not 8.

Simple Python Echo Server - Wrong Argument

import select
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host,port))
server.listen(5)
input = [server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == server:
# handle the server socket
client, address = server.accept()
input.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
data = s.recv(size)
if data:
s.send(data)
else:
s.close()
input.remove(s)
server.close()
Whenever I run this code, I get this error message for my argument for the while loop:
inputready,outputready,exceptready = select.select(input,[],[])
TypeError: argument must be an int, or have a fileno() method.
How can I fix this to make the server run properly? Sorry if this is a bad question, I'm new to python and I can't figure this out. Thanks.
Yeah found the solution to your problem their seem to be sys.stdin , the python IDLE GUI for some reason doesn't allow you to use sys.stdin.fileno() in your code, while if you run it in the command prompt or the terminal it will work fine on linux. Link
An if your using windows, you cant pass the sys.stdin as an argument to the select() function, as in windows it accepts only sockets as arguments. As Explained in the documentation Documentation
Note: File objects on Windows are not acceptable, but sockets are. On Windows, the underlying select() function is provided by the WinSock library, and does not handle file descriptors that don’t originate from WinSock.
So to mitigate the problem , such that it works on both windows and linux:
import select
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host,port))
server.listen(backlog)
input1 = [server]
running = 1
while running:
inputready,outputready,exceptready = select.select(input1,[],[])
for s in inputready:
if s == server:
# handle the server socket
client, address = server.accept()
input1.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
data = s.recv(size)
if data:
s.send(data)
else:
s.close()
input1.remove(s)
server.close()

How to create a timestamp for python

I currently have a TCP client code with logging which saves the sent data in a text file. I want the data sent to be saved in a folder which header is the time stamp of the sent data. Is that possible? I have tried using several methods but my code kept failing. Could someone give me a guide , would really be such a helping hand as I have been stuck on this for quite awhile.
This is how my code looks like now:
import socket
import thread
import sys
BUFF = 1024 # buffer size
HOST = '172.16.166.206'
PORT = 1234 # Port number for client & server to receive data
def response(key):
return 'Sent by client'
def logger(string, file_=open('logfile.txt', 'a'), lock=thread.allocate_lock()):
with lock:
file_.write(string)
file_.flush() # optional, makes data show up in the logfile more quickly, but is slower
sys.stdout.write(string)
def handler(clientsock, addr):
while 1:
data = clientsock.recv(BUFF) # receive data(buffer).
logger('data:' + repr(data) + '\n') #Server to receive data sent by client.
if not data:
break #If connection is closed by client, server will break and stop receiving data.
logger('sent:' + repr(response('')) + '\n') # respond by saying "Sent By Client".
if __name__=='__main__':
ADDR = (HOST, PORT) #Define Addr
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversock.bind(ADDR) #Binds the ServerSocket to a specific address (IP address and port number)
serversock.listen(5)
while 1:
logger('waiting for connection...\n')
clientsock, addr = serversock.accept()
logger('...connected from: ' + str(addr) + '\n') #show its connected to which addr
thread.start_new_thread(handler, (clientsock, addr))
You just need to import time module to generate the time stamp and create the directory named by time stamp.
Suppose you want to cut the log file into different folds by hour. The code will somewhat like bellow:
import time
import os
def logger(string, file_name='logfile.txt', lock=thread.allocate_lock()):
with lock:
time_stamp = time.strftime("%Y%m%d%H",time.localtime())
if not os.path.isdir(time_stamp): os.mkdir(time_stamp)
with open(os.path.join(time_stamp, file_name), "a") as file_:
file_.write(string)
file_.flush()
sys.stdout.write(string)
The code is not tested.
Check out the Python logging module at:
http://docs.python.org/2/howto/logging.html#logging-basic-tutorial

Transferring image files from sever to client using python socket programming

I am working on a project where images are taken by my android phone and are stored in folders in my SD card. I am working on a python script that needs to periodically move the folders from the SD to a particular folder in my PC. The phone and the PC are connected over the mobile Hotspot.
I wrote a socket program with my PC as client and the mobile as server. But I am facing some problems with it. Though I could not move folders i tried moving images from the folder and i am facing the following problems
the image is copied in the form of an unknown file format.
i am unable to iterate the process at the server side to move all the images present in the folder
at the client I am not able to store it in the location i want. I try to send the folder name and the file name from the server before sending the image but the client is not taking that file name i sent, instead it searches a folder in that name.
I also have a problem with the size of the names sent to the client, how do i randomly change the size at the client side depending on the name sent from the server.
I need someones help to sort this problem.
Here is the client side code
import socket,os
import time
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("192.168.43.1", 5005))
size = 1024
while True:
fln = client_socket.recv(size) # folder name
fn = client_socket.recv(size) # file name
fname = "E:\\Transfered\\"+fln+"\\"+fn
fp = open(fname,'w')
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
print "Data Received successfully"
exit()
#data = 'viewnior '+fname
#os.system(data)
My Server side code
import os
import sys,time
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5005))
server_socket.listen(5)
client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
sb = '/mnt/sdcard/sb'
while True:
files = os.listdir(sb)
pages = 0;
while (files):
print '\nMaybe, pending work'
for au in files:
if (au.find('d')>-1): # searching for folder with a d
os.chdir(sb+'/'+au)
imgFiles = os.listdir(sb+'/'+au)
images = [img for img in imgFiles if img.endswith('.jpg')]
print '\n%s user done' %au
client_socket.send(au)
pages = 0;
#copies all .img files in the folder from server to client
for imgs in images:
print imgs
client_socket.send(imgs)
file_name = open(imgs,'r')
while True:
strng = file_name.readline(1024)
if not strng:
break
client_socket.send(strng)
file_name.close()
print "Data sent successfully"
os.remove(sb+'/'+au+'/'+imgs)
pages = pages + 1
time.sleep(1)
os.chdir(sb)
os.rmdir(au)
else:
time.sleep(2)
exit()
The problem seems to be using readline() on a binary file at the server side:
file_name = open(imgs,'rb')
while True:
strng = file_name.readline()
readline() reads data from file up to the next '\n' character. Using it on a binary file may result in reading a very long buffer! (Maybe even up to EOF). In that case, using socket.send() may fail to deliver the entire data, and the return value (=bytes transmitted) should be checked. The possibilities for fixing that is:
using socket.sendall() when sending, will send the entire buffer.
or, alternatively (may use both)
using file_name.read(1024) - which will bound the amount of data read each cycle.
I have modified the code enough to solve many of my problems now the only problem i want to solve is the image transfer. I opened the a .jpg file at the client and wrote the data into it. But the final file size is just 1kb less that the original size. I guess my work will be done if I sort that out. Can some one help me with it.
heres the code
server:
import os
import sys,time
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5005))
server_socket.listen(5)
client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
sb = '/mnt/sdcard/sb'
while True:
files = os.listdir(sb)
pages = 0;
while (files):
print '\nMaybe, pending work'
for au in files:
if (au.find('d')>-1):
os.chdir(sb+'/'+au)
imgFiles = os.listdir(sb+'/'+au)
images = [img for img in imgFiles if img.endswith('.jpg')]
print '\n%s user done' %au
client_socket.send(au)
#copies all .img files in the folder from server to client
for imgs in images:
client_socket.send(imgs)
file_name = open(imgs,'rb')
while True:
strng = file_name.readline()
if not strng:
break
client_socket.send(strng)
file_name.close()
os.remove(sb+'/'+au+'/'+imgs)
print "Data sent successfully"
time.sleep(1)
os.chdir(sb)
os.rmdir(au)
else:
time.sleep(2)
exit()
Client:
import socket,os
import time
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("192.168.43.1", 5005))
dst="E:\\Kiosk\\"
while True:
#folder name
fln = client_socket.recv(4)
os.chdir(dst);
dst = "E:\\Kiosk\\"+fln+"\\"
if not os.path.exists(dst): os.makedirs(dst)
fname = client_socket.recv(4)
os.chdir(dst)
fname = fname+'.jpg'
fp = open(fname,'wb')
# image
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
print "Data Received successfully"
exit()
#time.sleep(10)
#data = 'viewnior '+fname
#os.system(data)

Categories