Basically working on an ftp client using raw sockets (nope, we can't cheat and use ftplib or something) and I seem to be stumped. I assumed that the way ftp works is, you open a socket, issue a port command, then whatever command you want after that (i.e. LIST) and then accept on a second socket that had it's IP and port number sent in the port command.
Unfortunately, each and every time I send the port command, the ftp server will tell me that the PORT command was successful, I then send LIST and try to accept on the 2nd socket... BUT IT WONT DO DIDDLY SQUAT!!!
My program just sits there, waiting for a connection... forever.
Here's my code, butfirst I'm going to just show the fraqment where I believe my problem lies:
Code:
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.bind(('',socket.INADDR_ANY))
s2.listen(1) #allow 1 pending connection
message = 'PORT ' + make_address(s2) + '\r\n'
s.send(message)
response = recv_complete(s)
print response
message = 'LIST\r\n'
s.send(message)
print message
s2.accept()
And the program waits forever on s2.accept(). For some reason, it seems that the ftp server aint trying to connect to that port.
Here's the rest:
Code:
#!/usr/bin/env python
############################################
# James Carr
# 4/26/04
# CSC410 Assignment 5
# Description:
############################################
import sys,socket,time,getpass, string, struct
def make_address(socketobj):
ip,port = s.getsockname()
print port
ip = struct.unpack('!L',socket.inet_aton(ip))[0]
h1 = (ip >> 24) & 0xff
h2 = (ip >> 16) & 0xff
h3 = (ip >> 8) & 0xff
h4 = (ip ) & 0xff
p1 = (port >> 8) & 0xff
p2 = (port ) & 0xff
portstr = '%d,%d,%d,%d,%d,%d' % (h1,h2,h3,h4,p1,p2)
return portstr
#################################################
def recv_complete(socketobj, timeout=''):
#setup to use non-blocking sockets
#if no data arrives for a specified
#period, time, it assumes the transaction
#is done
socketobj.setblocking(0)
total_data=[]
data = ''
begin = time.time()
if not timeout:
timeout=1
while 1:
if total_data and time.time() - begin > timeout:
break
wait=0
try:
data = socketobj.recv(1024)
if data:
total_data.append(data)
begin=time.time()
data='';wait=0
else:
time.sleep(0.1)
except:
pass
result = ''.join(total_data)
return result
##############################################
if len(sys.argv) != 3:
print """
Usage: ./proj5.py remotehost username
"""
sys.exit()
else:
hostname = sys.argv[1]
username = sys.argv[2]
port = 21 # We'll use port 21 as it's common
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((hostname, port))
except:
print '*** Connection Refused'
sys.exit()
print '*** Connection Established'
message = 'USER ' + username + '\r\n'
s.send(message)
response = recv_complete(s)
print response
message = getpass.getpass()
message = 'PASS ' + message + '\r\n'
s.send(message)
response = recv_complete(s)
print response
while 1:
print """
FTP COMMANDS:
----------------------
(1) Get a file
(2) Put a file
(3) directory listing
(4) Exit
----------------------
"""
command = input('Select an option: ')
if command == 1:
print 'dummy'
elif command == 2:
print 'dummy'
elif command == 3:
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.bind(('',socket.INADDR_ANY))
s2.listen(1) #allow 1 pending connection
message = 'PORT ' + make_address(s2) + '\r\n'
s.send(message)
response = recv_complete(s)
print response
message = 'LIST\r\n'
s.send(message)
print message
s2.accept()
response = recv_complete(s);
print response;
elif command == 4:
print '*** Disconnecting. '
s.send('QUIT\r\n')
response = recv_complete(s)
print response
s.close()
sys.exit()
else:
print 'That is not a valid command, please try again.'
incomplete at the moment. I'm just POSITIVE once I can get this port crap working and recieve a directory listing, I'll be pretty much done, and the rest will fall into place.
Thanks