Posts: 324
Threads: 114
Joined: Jan 2018
09-14-2018, 11:59 PM
(This post was last modified: 09-15-2018, 12:44 AM by QMark.)
Hi, I'm reading this packt book and I am getting invalid syntax when being told what to do on the dot.
I actually think its because I'm not getting the networking concept behind this. Could someone please help?
I know how TCP works but it might be that I am also having trouble understanding the code I am being told to write.
Could somone please explain and if possible send me maybe a useful link? Here is my code:
Code: import sys, socket
try:
rfc_number = int(sys.argv[1])
except (IndexError, ValueError):
print('Must supply an RFC number as first argument')
sys.exit(2)
host = 'www.ietf.org'
port = 80
sock = socket.create_connection((host, port))
req = (
'GET/rfc/rfc{rfcnum}.txt HTTP/1.1\r\n'
'Host: {host}:{port}\r\n'
'User-Agent: Python {version}\r\n'
'Connection: close\r\n'
'\r\n'
)
req = req.format(
rfcnum=rfc_number
host=host
port=port
version=sys.version.info[0]
)
sock.sendall(req.encode('ascii'))
rfc_raw = bytearray()
while True:
buf = sock.recv(4096)
if not len(buf):
break
rfc_raw += buf
rfc = rfc_raw.decode('utf-8')
print(rfc)
Here is the link to the pdf of the book:
https://ufile.io/tcr73
It's on pages 21 to 22 the code.
Could someone also help please explain a little bit of what it's telling me to write or what to lookup on Google to understand this?
Thanks. This stuff is REALLY difficult.
Also, I think there is a known data structure in this and I think I need to know how that works to understand this. Could someone help me figure out which data structure I'm working with?
THANK YOU SO MUCH!!!
Best,
QMark
PS
If I wanted to rewrite the code differently afterwards would that be to continue this thread or another thread?
Syntax error
Code: Traceback (most recent call last):
File "/usr/lib/python3.6/code.py", line 91, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "/snap/pycharm-community/83/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "/snap/pycharm-community/83/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/home/adam/.PyCharmCE2018.2/config/scratches/firstTCP_program.py", line 23
host=host
^
SyntaxError: invalid syntax
Posts: 324
Threads: 114
Joined: Jan 2018
Ok, I got the code working because of fixing a syntax error where I had to add in commas but two questions still unanswered:
1. hard time understanding the code from the book
2. I am gonna try to recode this afterwards and should that be same thread or different thread to see if that works? If same, then my question isn't yet over lol.
Posts: 8
Threads: 2
Joined: Sep 2018
So from my understanding you want to make a GET request and then receive the content sent back by the server right?
There are 2 things I must say before I can help:
- Do you want to make this strictly with socket module? Because if not, you can use the requests module in python and is much easier.
- Could you elaborate more about what are you trying to achieve?
A simple google search directed me to these links: creating-a-raw-http-request-with-sockets python-socket-get
I would suggest you have a look at how sockets work. You can always google about this subject because there are a lot of tutorials out there.
If I got all of this wrong then my bad xD
Posts: 1,416
Threads: 377
Joined: Jun 2015
I tried explaining as well as I could by adding comments to your code. Honestly I may be wrong on some parts, it's been a while since I did python.
But yes, Ditto ^ Highly suggest you read up on sockets.
Code: import sys, socket
"""
Every protocol as an RFC number. This script is started together with the RFC number supplied by you? eg.
File: tcptest.py
make it executable: chmod +x tcptest.py
execute: ./tcptest
Pass RFC number:
./tcptest 793
https://tools.ietf.org/html/rfc793
"""
try:
rfc_number = int(sys.argv[1])
except (IndexError, ValueError):
print('Must supply an RFC number as first argument')
sys.exit(2)
# ^ If you do not pass an RFC number, error exit.
# Declare variables with connection details for your socket. IE ietf.org on port 80.
host = 'www.ietf.org'
port = 80
# Creates a socket to host and port
sock = socket.create_connection((host, port))
# request the RFC document corresponding to the integer you passed as variable at the top.
req = (
'GET/rfc/rfc{rfcnum}.txt HTTP/1.1\r\n' # Get request to RFC file
'Host: {host}:{port}\r\n' # Browser header, ietf.org port 80
'User-Agent: Python {version}\r\n' # Browser header, tells webserver you are not a webbrowser but you are a python script.
'Connection: close\r\n' # Close the connection when request is done
'\r\n'
)
"""
# All {things} inside the curly bracket above on the req var is replaced below with the variables desired using format.
For example:
name = input("What's your name?\n")
print(name)
output = "Your name is {thing}!"
output = output.format(thing=name)
print(output)
Something like that
"""
req = req.format(
rfcnum=rfc_number
host=host
port=port
version=sys.version.info[0]
)
# The socket sends your request to get the RFC document. And encodes it in ascii
sock.sendall(req.encode('ascii'))
rfc_raw = bytearray() #set up a byte array for raw data. (Byte array= data structure to store sequence of integers.) Why? The socket encoded request into asciii which is basically integers that correspond to the ascii table?
while True: # While the byte array is true, do loop.
buf = sock.recv(4096) # Recieve the socket response into a buffer of 4096 bytes? (sorry I it's been a while I read python)
if not len(buf): # if the lenght of the data overflows the buffer, break look
break
rfc_raw += buf #insert the buffer data into rfc_raw var
rfc = rfc_raw.decode('utf-8') #use the ascii integers from the byte array and decode it to utf8. IE strings, characters. Also means the while loop stops, since byte array is not true.
print(rfc) # print the UTF8 decoded RFC document
https://whatis.techtarget.com/definition/sockets
https://beej.us/guide/bgnet/
Posts: 324
Threads: 114
Joined: Jan 2018
09-16-2018, 04:37 AM
(This post was last modified: 09-16-2018, 04:40 AM by QMark.)
Could someone please explain this one other last error because its literally what the book had me type:
Code: adam@adam-Inspiron-5558:~/.PyCharmCE2018.2/config/scratches$ python firstTCP_program.py 782
Traceback (most recent call last):
File "firstTCP_program.py", line 21, in <module>
req = req.format(
AttributeError: 'tuple' object has no attribute 'format'
And while your doing that I'm reading the articles lol.
Posts: 8
Threads: 2
Joined: Sep 2018
(09-16-2018, 04:37 AM)QMark Wrote: Could someone please explain this one other last error because its literally what the book had me type:
Code: adam@adam-Inspiron-5558:~/.PyCharmCE2018.2/config/scratches$ python firstTCP_program.py 782
Traceback (most recent call last):
File "firstTCP_program.py", line 21, in <module>
req = req.format(
AttributeError: 'tuple' object has no attribute 'format'
And while your doing that I'm reading the articles lol.
Have you tried to google the error before asking?
You can have a look at what a tuple is.
Posts: 34
Threads: 8
Joined: Apr 2016
Your using format on a tuple, which is wrong
a tuple is a list of lists
Posts: 324
Threads: 114
Joined: Jan 2018
09-18-2018, 09:28 PM
(This post was last modified: 09-18-2018, 09:32 PM by QMark.)
I guess I am gonna look up tuples, lol. Thanks will do.
(09-16-2018, 11:17 AM)illmanors Wrote: Your using format on a tuple, which is wrong
a tuple is a list of lists
So is there a way to do (I know this gets an error), something like this:
Code: for a in req:
req[a] = req[a].format(
rfcnum=rfc_number,
host=host,
port=port,
version=sys.version.info[0][color=#a9b7c6][size=x-small][font=DejaVu Sans Mono]
)[/font][/size][/color]
Posts: 34
Threads: 8
Joined: Apr 2016
09-18-2018, 10:43 PM
(This post was last modified: 09-18-2018, 10:50 PM by illmanors.)
(09-18-2018, 09:28 PM)QMark Wrote: I guess I am gonna look up tuples, lol. Thanks will do.
(09-16-2018, 11:17 AM)illmanors Wrote: Your using format on a tuple, which is wrong
a tuple is a list of lists
So is there a way to do (I know this gets an error), something like this:
Code: for a in req:
req[a] = req[a].format(
rfcnum=rfc_number,
host=host,
port=port,
version=sys.version.info[0][color=#a9b7c6][size=x-small][font=DejaVu Sans Mono]
)[/font][/size][/color]
Your loading in the tuple, and work them down one by one (for a in req)
which means your having a list , you define the items in the list as a (for a in req)
so if the list is ['rfc_number','host','port'] , the rfc_number would be a[0] , host be a[1] , port be a[2]
Code: for a in req:
req[a] = req[a].format(
rfcnum=a[0],
host=a[1],
port=a[2],
version=sys.version.info[0][color=#a9b7c6][size=x-small][font=DejaVu Sans Mono]
)[/font][/size][/color]
?????
Edit : i'm not 100% sure what your trying to do here
Posts: 324
Threads: 114
Joined: Jan 2018
(09-18-2018, 10:43 PM)illmanors Wrote: (09-18-2018, 09:28 PM)QMark Wrote: I guess I am gonna look up tuples, lol. Thanks will do.
(09-16-2018, 11:17 AM)illmanors Wrote: Your using format on a tuple, which is wrong
a tuple is a list of lists
So is there a way to do (I know this gets an error), something like this:
Code: for a in req:
req[a] = req[a].format(
rfcnum=rfc_number,
host=host,
port=port,
version=sys.version.info[0][color=#a9b7c6][size=x-small][font=DejaVu Sans Mono]
)[/font][/size][/color]
Your loading in the tuple, and work them down one by one (for a in req)
which means your having a list , you define the items in the list as a (for a in req)
so if the list is ['rfc_number','host','port'] , the rfc_number would be a[0] , host be a[1] , port be a[2]
Code: for a in req:
req[a] = req[a].format(
rfcnum=a[0],
host=a[1],
port=a[2],
version=sys.version.info[0][color=#a9b7c6][size=x-small][font=DejaVu Sans Mono]
)[/font][/size][/color]
?????
Edit : i'm not 100% sure what your trying to do here
I'm trying to take each dictionary within the tuple and format each one.
|