I wrote the following script in python:
#!/usr/bin/python
import socket
import sys
import os
host=sys.argv[1]
port=sys.argv[2]
if len(sys.argv) != 3:
print 'Usage: python %s <HostName> <PortNumber>' % (sys.argv[0])
sys.exit();
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print 'Failed to creat socket. Error code: ' + str(msg[0]) + ' Error message: ' + msg[1]
sys.exit();
try:
host_ip=socket.gethostbyname(host)
except socket.gaierror:
print 'Host name could not be resolved. Exiting...'
sys.exit();
print 'IP address of ' + host + ' is ' + host_ip + ' .'
try:
s.connect((host_ip, port)) #OR s.connect((host_ip, sys.argv[2]))
except socket.error, (value,message):
if s:
s.close();
print 'Socket connection is not established!\t' + message
sys.exit(1);
print 'Socket connected to ' + host + 'on IP ' + host_ip + 'on port number ' + port + '.'
But when I run it this error occures:
s.connect((host_ip, port))
return getattr(self._sock,name)(*args)
TypeError: an integer is required
What is wrong here?
Thanks
The error message is the answer.
port shall be an integer and you are passing in str
before you call s.connect((host_ip, port)) do
port = int(port)
You should use argparse to process your arguments. It provides many useful features in addition to making it easy to fix your immediate problem (not making the port number an integer). Replace
host=sys.argv[1]
port=sys.argv[2]
if len(sys.argv) != 3:
print 'Usage: python %s <HostName> <PortNumber>' % (sys.argv[0])
sys.exit();
with
import argparse
p = argparse.ArgumentParser()
p.add_argument("host")
p.add_argument("port", type=int)
args = p.parse_args()
# And optionally
host = args.host
port = args.port
connect() requires an integer for the port argument, and since you accepted port as an argument it's a string. Make sure you typecast it as an int - s.connect((host_ip, int(port)).
The sys.argv list is a list of strings, so you should convert it to an integer with the build-in int() function:
port = int(sys.argv[2])
Related
I'm currently working on this Python port scanner, I'm trying to implement a feature that will allow this port scanner to scan a local subnet.
Currently when the target IP ends in .0, it scans every IP in that subnet range, (.1 - .255) except when I run the program, returns 'cannot resolve , unknown host' for every single IP within the subnet range. The code I currently have is below:
# import modules used in port scanner
import optparse
from socket import *
from threading import *
import ipaddress
# connect-scan function, deals with connecting to the host / determining if ports are open / closed, takes arguments tgtHost, tgtPort
def connScan(tgtHost, tgtPort):
try:
connSkt = socket(AF_INET, SOCK_STREAM)
connSkt.connect((tgtHost, tgtPort))
connSkt.send('\r\n')
result = connSkt.recv(100)
# prints result if port is open
print '[+] ' + str(tgtPort) + '/tcp open'
except:
# prints result if port is closed
print '[-] ' + str(tgtPort) + '/tcp closed'
finally:
connSkt.close()
# port-scan function, takes arguments tgtHost, tgtPorts
def portScan(tgtHost, tgtPorts):
try:
# tries to get target IP address
tgtIP = gethostbyname(tgtHost)
except:
# if unsuccesful, prints out following result
print '[-] cannot resolve ' + unicode(tgtHost) + ': unknown host'
return
try:
# tries to get target address
tgtName = gethostbyaddr(tgtIP)
print '\n[+] scan results for: ' + tgtName[0]
except:
print '\n[+] scan results for: ' + tgtIP
# sets default time out to 1
setdefaulttimeout(1)
# for every port in tgtPorts
for tgtPort in tgtPorts:
# creates thread, target is connScan function, arguments are tgtHost, int(tgtPort)
t = Thread(target=connScan, args=(tgtHost, int(tgtPort)))
# starts the thread
t.start()
def main():
parser = optparse.OptionParser('usage %prog -t <target-host> -p <target-port(s)>')
parser.add_option('-t', dest='tgtHost', type='string', help='specify target host, for local subnet, use 192.168.1.0 (scans range 192.168.1.1 - 192.168.1.255')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port(s), seperated by a comma, seperate ranges with a -')
(options, args) = parser.parse_args()
if (options.tgtHost == None) | (options.tgtPort == None):
print parser.usage
exit(0)
else:
tgtHost = options.tgtHost
if tgtHost.endswith('.0'):
hosts = ipaddress.ip_network(unicode(tgtHost+'/24'))
else:
hosts = [tgtHost]
# allows ranges of ports to be used, when seperated by a -
if '-' in str(options.tgtPort):
tgtPorts = options.tgtPort.split('-')
tgtPorts = range(int(tgtPorts[0]),int(tgtPorts[1]))
else:
tgtPorts = str(options.tgtPort).split(',')
for tgtHost in hosts:
portScan(tgtHost, tgtPorts)
if __name__ == '__main__':
main()
I've been trying to find the solution for this, however have come up empty. Does anyone know whats wrong with the code?
This question already has answers here:
TypeError: 'str' does not support the buffer interface
(7 answers)
Closed 8 years ago.
import socket
import sys
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print ('Failed to create socket')
sys.exit();
print ('Socket Created', s)
host = 'www.google.com'
port = 80
try:
remote_ip = socket.gethostbyname(host)
except socket.gaierror:
print ('Hostname could not be resolved. Exiting')
sys.exit()
print ('Ip address of "' + host + '" is: ' + remote_ip )
s.connect((remote_ip, port))
print ('Socket Connected to ' + host + ' on ip ' + remote_ip)
message = 'GET / HTTP/1.1\r\n\r\n'
try:
s.sendall(message)
except socket.error:
print ('Send Failed')
sys.exit()
print ('Message send successfully')
reply = s.recv(4096)
print ('reply')
In Python 3, str is a unicode string, which could have a wide variety of byte representations. Strings are unicode by default.
To get a plain byte string, you can prefix the string with b, such as b'GET / HTTP/1.1\r\n\r\n'. You can also use the encode method of a unicode string to get a specific encoding.
To learn more about Unicode, you should probably read the Python 3 Unicode HOWTO.
I can send messages in the form of strings but I cannot send integers to the server.
What I have done is this:
import socket #for sockets
import sys #for exit
try:
#create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sys.exit();
print 'Socket Created'
host = 'localhost'
port = 6000
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
print 'Ip address of ' + host + ' is ' + remote_ip
#Connect to remote server
s.connect((remote_ip , port))
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
nb = input('Choose a number')
print ('Number%s \n' % (nb))
#Send some data to remote server
#message = nb
try :
#Set the whole string
s.send(mySocket, nb, sizeof(int),0);
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
print 'Message send successfully'
you can use int() and str() function for convert integer to string and send it
and in other side with int() function convert it to integer
look at these links
http://docs.python.org/2/library/functions.html#int
http://docs.python.org/2/library/functions.html#str
So I am just getting into python and trying out some stuff. To start, I am making a server that does simple stuff like "GET"s stored text, "STORE"s new text over the old stored text, and "TRANSLATE"s lowercase text into uppercase. But I have a few questions. Here is my code so far:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
while 1:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
data = conn.recv(1024)
reply = 'OK...' + data
if not data: break
conn.send(data)
conn.close()
s.close()
To start changing text from a client into uppercase, from my other programming knowledge, I assume I'd store the client's text in a variable and then run a function on it to change it to uppercase. Is there such a function in python? Could someone please give me a snippet of how this would look?
And lastly, how would I do something like a GET or STORE in python? My best guess would be:
data = conn.recv(1024)
if data == GET: print text
if data == STORE: text = data #Not sure how to reference the text that the client has entered
Thank you so much for any help! :)
Note to self:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
# Accept the connection
(conn, addr) = s.accept()
print 'Server: got connection from client ' + addr[0] + ':' + str(addr[1])
storedText = 'Hiya!'
while 1:
data = conn.recv(1024)
tokens = data.split(' ', 1)
command = tokens[0]
if command == 'GET':
print addr[0] + ':' + str(addr[1]) + ' sends GET'
reply = storedText
elif command == 'STORE':
print addr[0] + ':' + str(addr[1]) + ' sends STORE'
storedText = tokens[0]
reply = '200 OK\n' + storedText
elif command == 'TRANSLATE':
print addr[0] + ':' + str(addr[1]) + ' sends TRANSLATE'
storedText = storedText.upper()
reply = storedText
elif command == 'EXIT':
print addr[0] + ':' + str(addr[1]) + ' sends EXIT'
conn.send('200 OK')
break
else:
reply = '400 Command not valid.'
# Send reply
conn.send(reply)
conn.close()
s.close()
I see that you're quite new to Python. You can try to find some code example, and you should also learn how to interpret the error message. The error message will give you the line number where you should look at. You should consider that line or previous line, as the error may be caused by previous mistakes.
Anyway, after your edits, do you still have indentation error?
On your real question, first, the concept.
To run client/server, you'll need two scripts: one as the client and one as the server.
On the server, the script will just need to bind to a socket and listen to that connection, receive data, process the data and then return the result. This is what you've done correctly, except that you just need to process the data before sending response.
For starter, you don't need to include the accept in the while loop, just accept one connection, then stay with it until client closes.
So you might do something like this in the server:
# Accept the connection once (for starter)
(conn, addr) = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
stored_data = ''
while True:
# RECEIVE DATA
data = conn.recv(1024)
# PROCESS DATA
tokens = data.split(' ',1) # Split by space at most once
command = tokens[0] # The first token is the command
if command=='GET': # The client requests the data
reply = stored_data # Return the stored data
elif command=='STORE': # The client want to store data
stored_data = tokens[1] # Get the data as second token, save it
reply = 'OK' # Acknowledge that we have stored the data
elif command=='TRANSLATE': # Client wants to translate
stored_data = stored_data.upper() # Convert to upper case
reply = stored_data # Reply with the converted data
elif command=='QUIT': # Client is done
conn.send('Quit') # Acknowledge
break # Quit the loop
else:
reply = 'Unknown command'
# SEND REPLY
conn.send(reply)
conn.close() # When we are out of the loop, we're done, close
and in the client:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
while True:
command = raw_input('Enter your command: ')
if command.split(' ',1)[0]=='STORE':
while True:
additional_text = raw_input()
command = command+'\n'+additional_text
if additional_text=='.':
break
s.send(command)
reply = s.recv(1024)
if reply=='Quit':
break
print reply
Sample run (first run the server, then run the client) on client console:
Enter your command: STORE this is a text
OK
Enter your command: GET
this is a text
Enter your command: TRANSLATE
THIS IS A TEXT
Enter your command: GET
THIS IS A TEXT
Enter your command: QUIT
I hope you can continue from there.
Another important point is that, you're using TCP (socket.SOCK_STREAM), so you can actually retain the connection after accepting it with s.accept(), and you should only close it when you have accomplished the task on that connection (accepting new connection has its overhead). Your current code will only be able to handle single client. But, I think for starter, this is good enough. After you've confident with this, you can try to handle more clients by using threading.
I'm new to python and going through a book, Core Python Applications 3rd Edition. This is the the first example and already I'm stumped with it. Here's the code with the error at the end.
#!/usr/bin/env python
from socket import *
from time import ctime
HOST = ' '
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print 'waiting for connection...'
tcpCliSock, addr = tcpSerSock.accept()
print "...connected from:", addr
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
tcpCliSock.send("[%s] %s" % (ctime(), data))
tcpCliSock.close()
tcpSerSock.close()
Traceback (most recent call last):
File "tsTserv.py", line 12, in <module>
tcpSerSock.bind(ADDR)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
What does this mean?
It means that your given host name ' ' is invalid (gai stands for getaddrinfo()).
As NPE already states, maybe an empty string '' would be more appropriate than a space ' '.
The
HOST = ' '
should read
HOST = ''
(i.e. no space between the quotes).
The reason you're getting the error is that ' ' is not a valid hostname. In this context, '' has a special meaning (it basically means "all local addresses").