python socket client program 2(Get request) - python

Thanks all for solving my first question.But there is a final problem.
#import socket module
import sys
import httplib
from socket import *
serverName = sys.argv[1]
serverPort = int(sys.argv[2])
filename = sys.argv[3]
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
clientSocket.send("GET /filename")
while True:
data = clientSocket.recv(1024)
if not data:
break
print data,filename
clientSocket.close()
FInally, i can't receive the content with the certain filname.I think the point is in "/"
How can i solve it??

Have you tried using the python requests package?
Either way, you have a problem here:
clientSocket.send("GET /filename")
Should (at the very least) be:
clientSocket.send("GET /%s" % filename)
When you write filename inside the string, it will not evaluate that to the variable filename instead, you need to use string formatting

Is this program communicate with HTTP server?
Then, it should send CR+LF twice to correctly denote the end of HTTP header.
clientSocket.send("GET /{}\r\n\r\n".format(filename))

Related

Transfer contents of a folder over network by python

I am facing a problem writing a program to send contents of a folder over the network by using Python. There are a lot of examples out there, all the examples I found are assuming the receiver side knew name of the file he want to receive. The program I am trying to do assuming that the receiver side agree to receive a files and there is no need to request a file by its name from the server. Once the connection established between the server and the client, the server start send all files inside particular folder to the client. Here is a image to show more explanation:example here
Here are some programs that do client server but they send one file and assume the receiver side knew files names, so the client should request a file by its name in order to receive it.
Note: I apologies for English grammar mistakes.
https://www.youtube.com/watch?v=LJTaPaFGmM4
http://www.bogotobogo.com/python/python_network_programming_server_client_file_transfer.php
python socket file transfer
Here is best example I found:
Server side:
import sys
import socket
import os
workingdir = "/home/SomeFilesFolder"
host = ''
skServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
skServer.bind((host, 1000))
skServer.listen(10)
print "Server Active"
bFileFound = 0
while True:
Content, Address = skServer.accept()
print Address
sFileName = Content.recv(1024)
for file in os.listdir(workingdir):
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(1024)
while sRead:
Content.send(sRead)
sRead = fUploadFile.read(1024)
print "Sending Completed"
break
Content.close()
skServer.close()
Client side:
import sys
import socket
skClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
skClient.connect(("ip address", 1000))
sFileName = raw_input("Enter Filename to download from server : ")
sData = "Temp"
while True:
skClient.send(sFileName)
sData = skClient.recv(1024)
fDownloadFile = open(sFileName, "wb")
while sData:
fDownloadFile.write(sData)
sData = skClient.recv(1024)
print "Download Completed"
break
skClient.close()
if there is a way to eliminate this statement from the client side:
sFileName = raw_input("Enter Filename to download from server : ")
and make the server side send all files one by one without waiting for the client to pick a file.
Here's an example that recursively sends anything in the "server" subdirectory to a client. The client will save anything received in a "client" subdirectory. The server sends for each file:
The path and filename relative to the server subdirectory, UTF-8-encoded and terminated with a newline.
The file size in decimal as a UTF-8-encoded string terminated with a newline.
Exactly "file size" bytes of file data.
When all files are transmitted the server closes the connection.
server.py
from socket import *
import os
CHUNKSIZE = 1_000_000
sock = socket()
sock.bind(('',5000))
sock.listen(1)
while True:
print('Waiting for a client...')
client,address = sock.accept()
print(f'Client joined from {address}')
with client:
for path,dirs,files in os.walk('server'):
for file in files:
filename = os.path.join(path,file)
relpath = os.path.relpath(filename,'server')
filesize = os.path.getsize(filename)
print(f'Sending {relpath}')
with open(filename,'rb') as f:
client.sendall(relpath.encode() + b'\n')
client.sendall(str(filesize).encode() + b'\n')
# Send the file in chunks so large files can be handled.
while True:
data = f.read(CHUNKSIZE)
if not data: break
client.sendall(data)
print('Done.')
The client creates a "client" subdirectory and connects to the server. Until the server closes the connection, the client receives the path and filename, the file size, and the file contents and creates the file in the path under the "client" subdirectory.
client.py
from socket import *
import os
CHUNKSIZE = 1_000_000
# Make a directory for the received files.
os.makedirs('client',exist_ok=True)
sock = socket()
sock.connect(('localhost',5000))
with sock,sock.makefile('rb') as clientfile:
while True:
raw = clientfile.readline()
if not raw: break # no more files, server closed connection.
filename = raw.strip().decode()
length = int(clientfile.readline())
print(f'Downloading {filename}...\n Expecting {length:,} bytes...',end='',flush=True)
path = os.path.join('client',filename)
os.makedirs(os.path.dirname(path),exist_ok=True)
# Read the data in chunks so it can handle large files.
with open(path,'wb') as f:
while length:
chunk = min(length,CHUNKSIZE)
data = clientfile.read(chunk)
if not data: break
f.write(data)
length -= len(data)
else: # only runs if while doesn't break and length==0
print('Complete')
continue
# socket was closed early.
print('Incomplete')
break
Put any number of files and subdirectories under a "server" subdirectory in the same directory as server.py. Run the server, then in another terminal run client.py. A client subdirectory will be created and the files under "server" copied to it.
So... I've decided I've posted enough in comments and I might as well post a real answer. I see three ways to do this: push, pull, and indexing.
Push
Recall the HTTP protocol. The client asks for a file, the server locates it, and sends it. So get a list of all the files in a directory and send them all together. Better yet, tar them all together, zip them with some compression algorithm, and send that ONE file. This method is actually pretty much industry standard among Linux users.
Pull
I identifed this in the comments, but it works like this:
Client asks for directory
Server returns a text file containing the names of all the files.
Client asks for each file.
Index
This technique is the least mutable of the three. Keep an index of all the files in the directory, named INDEX.xml (funny enough, you could model the entire directory tree in xml.) your client will request the xml file, then walk the tree requesting other files.
you need to send os.listdir() by using json.dumps() and encode it as utf-8
at client side you need to decode and use json.loads() so that list will be transfer to client
place sData = skClient.recv(1024) before sFileName = raw_input("Enter Filename to download from server : ") so that the server file list can be display
you can find at here its a interesting tool
https://github.com/manoharkakumani/mano

copying same file name from client to server using tcp protocol with same size of file

This is the client and server program where a client sends a file to server to save in the server. There is a issuse in that same file name is not getting copied on the server with same file size
Please help me in this
Client program
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost",9999))
path=raw_input("Please enter the complete PATH of your file : ")
f=open (path, "rb")
l = f.read(256)
while (l):
s.sendall(l)
l = f.read(10000)
s.close()
Server Program
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",9999))
s.listen(10)
while True:
s, address = s.accept()
print address
i=1
f = open( str(i),'wb') #open in binary
#i=i+1
while (True):
l=s.recv(256)
#while (l):
f.write(l)
l=s.recv(256)
print 'File recieve succesfully'
f.close()
#sc.close()
s.close()
Thanks in advance
Start by walking through the code and thinking about what the client knows about the data it is sending and what the server knows about the data it is receiving. You will have to send 2 types of messages: the data and the filename. How you do that is up to you.
Without over-thinking it, maybe try writing the filename first (followed by a newline or special character) then send the file data. On the server side accept the connection, read in data until you find a newline character (that's the filename), then receive the rest of the data and write it to the file.
Also, the server code you've provided doesn't work, at least I don't think, since you never break out of your while True loops.

Does File Exist on Client Python TCP server

I am trying to make a TCP port server in python. Here is my code so far:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('',4000))
sock.listen(1)
while 1:
client, address = sock.accept()
fileexists = client.RUNCOMMAND(does the file exist?)
if fileexists = 0:
client.close()
else if:
filedata = client.RUNCOMMAND(get the contents of the file)
if filedata = "abcdefgh":
client.send('Transfer file accepted.')
else:
client.send('Whoops, seems like you have a corrupted file!')
client.close()
I just have no idea how to run a command (RUNCOMMMAND) that would check if a file exists on the client.
Also, is there a way to check what operating system the client is on to run different commands (eg. linux will have a file finder different command than windows). And I totally understand if this isn't possible, but I am really hoping that there is a way to do this.
Thank you very much.
XMLRPC may help you.
XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport.
http://docs.python.org/2/library/xmlrpclib.html
You might want to look at the very handy bottle.py micro server. its great for small server tasks like this and you get the Http protocol on top of this. You just include one file with your code. http://bottlepy.org
here is code that will work from http://blah:8090/get/file or http://blah:8090/exists/file so to see the contents of /etc/hosts would be http://blah:8090/get/etc/hosts
#!/usr/bin/python
import bottle
import os.path
#bottle.route("/get/<filepath:path>")
def index(filepath):
filepath = "/" + filepath
print "getting", filepath
if not os.path.exists(filepath):
return "file not found"
print open(filepath).read() # prints file
return '<br>'.join(open(filepath).read().split("\n")) # prints file with <br> for browser readability
#bottle.route("/exists/<filepath:path>")
def test(filepath):
filepath = "/" + filepath
return str(os.path.exists(filepath))
bottle.run(host='0.0.0.0', port=8090, reloader=True)
the reloader option on the run method allows you to edit the code without manually restarting the server. Its quite handy.

Can't send correct value over a socket using Python

I'm new to using Python and sockets in general (only started yesterday) so I've been having a lot of issues trying to set up a TCP client and server. The issue I'm having is that I want to send a key from the server to the client. I know that the server grabs the key correctly as it prints out the correct key, however it has a 0 appended to it in a new line and when the key is sent to the client the only thing that is displayed is " b'0' ".
I've made very little progress due to my lack of experience and after searching for hours I still haven't found a solution to my problem.
Here is the server code:
import os
from socket import * #import the socket library
HOST = '' #We are the host
PORT = 29876
ADDR = (HOST, PORT)
BUFFSIZE = 4096
message = 'Hello, World!'
serv = socket( AF_INET,SOCK_STREAM)
serv.bind(ADDR,)
serv.listen(5)
print ('listening...')
conn,addr = serv.accept()
print (conn,addr)
print ('...connected')
key = os.system("cat ~/.ssh/id_rsa.pub")
conn.send(str(key))
print (key)
conn.close()
Here is the client code
from socket import *
import os
HOST = 'xxx.xxx.xxx.xxx'
PORT = 29876
ADDR = (HOST,PORT)
BUFFSIZE = 4096
message = "Hello, World!"
cli = socket( AF_INET, SOCK_STREAM)
cli.connect(ADDR,)
data = cli.recv(BUFFSIZE)
print (data)
cli.close()
As you can tell from my code I'm using Python 3.3
Any help with this issue is greatly appreciated.
os.system() does not return the process's output, but the return value (ie. integer 0).
If you only want to read a file, do it manually:
with open(os.path.expanduser("~/.ssh/id_rsa.pub")) as f:
key = f.read()
conn.sendall(key)
If you need process output, read the documentation for the subprocess module.

How do I get the external IP of a socket in Python?

When I call socket.getsockname() on a socket object, it returns a tuple of my machine's internal IP and the port. However, I would like to retrieve my external IP. What's the cheapest, most efficient manner of doing this?
This isn't possible without cooperation from an external server, because there could be any number of NATs between you and the other computer. If it's a custom protocol, you could ask the other system to report what address it's connected to.
The only way I can think of that's guaranteed to give it to you is to hit a service like http://whatismyip.com/ to get it.
https://github.com/bobeirasa/mini-scripts/blob/master/externalip.py
'''
Finds your external IP address
'''
import urllib
import re
def get_ip():
group = re.compile(u'(?P<ip>\d+\.\d+\.\d+\.\d+)').search(urllib.URLopener().open('http://jsonip.com/').read()).groupdict()
return group['ip']
if __name__ == '__main__':
print get_ip()
You'll need to use an external system to do this.
DuckDuckGo's IP answer will give you exactly what you want, and in JSON!
import requests
def detect_public_ip():
try:
# Use a get request for api.duckduckgo.com
raw = requests.get('https://api.duckduckgo.com/?q=ip&format=json')
# load the request as json, look for Answer.
# split on spaces, find the 5th index ( as it starts at 0 ), which is the IP address
answer = raw.json()["Answer"].split()[4]
# if there are any connection issues, error out
except Exception as e:
return 'Error: {0}'.format(e)
# otherwise, return answer
else:
return answer
public_ip = detect_public_ip()
print(public_ip)
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("msn.com",80))
s.getsockname()
print (urllib.urlopen('http://automation.whatismyip.com/n09230945.asp').read())
The most simple method of getting a public IP is by using this
import requests
IP = requests.get('https://api.ipify.org/').text
print(f'Your IP is: {IP}')
Using the address suggested in the source of http://whatismyip.com
import urllib
def get_my_ip_address():
whatismyip = 'http://www.whatismyip.com/automation/n09230945.asp'
return urllib.urlopen(whatismyip).readlines()[0]
You need to make connection to an external Server And Get Your Public IP From The Response
like this:
import requests
myPublic_IP = requests.get("http://wtfismyip.com/text").text.strip()
print("\n[+] My Public IP: "+ myPublic_IP+"\n")

Categories