how to code TCP in python?
#1
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
Reply
#2
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.
Reply
#3
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:
  1. 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.
  2. 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
Reply
#4
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/
Reply
#5
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.
Reply
#6
(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.
Reply
#7
Your using format on a tuple, which is wrong

a tuple is a list of lists
Reply
#8
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]
Reply
#9
(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
Reply
#10
(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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python Ebook Collection [89 Files] Insider 15 88,306 08-12-2021, 08:02 PM
Last Post: zzeuss
  NSA Python Training Insider 4 28,879 08-12-2021, 02:14 AM
Last Post: hworth
  Having an issue writing a python script with vim FancyBear 4 22,555 01-03-2021, 11:27 PM
Last Post: FancyBear
  Python Data structures and algorithms resources skinnyj0shua 1 17,395 12-23-2020, 12:52 PM
Last Post: enmafia2