Today, I'm spending the day learning in public about socket programming (in Python 🐍).

My starting point is this:

β€œI think sockets are like tunnels/roads that allow different programs to talk to each other directly.”

This 🧡 will evolve as I learn and experiment πŸ‘‡
My idea is to experiment a bit with sockets in the REPL, then probably build a toy program that uses sockets to send random information through sockets.

I'm starting off with the β€œSocket Programming HOWTO” in the Python docs (docs.python.org/3/howto/socket…).

Let's go πŸš€
Alright, so, I'm not completely wrong in my intuitive understanding of sockets.
The HOWTO says

β€œOf the various forms of IPC, sockets are by far the most popular.”

IPC – Inter-Process Communication.

Turns out sockets are a good cross-platform IPC mechanism.
So, it seems there are two types of sockets:

πŸ‘‰ server sockets
πŸ‘‰ client sockets

Server sockets sit there, listening, waiting for β€œclients” to connect, and then handle those connections by doing something useful.

Client sockets want to connect to the servers to talk to them.
You don't need a lot of code to create a socket server in Python 🐍

Here is a snippet that creates a socket server that is only visible to your own computer.

If you run this, the code hangs: the `.accept` call is waiting for a client to connect to the server! Image
I had this crazy idea:

Can I connect my browser to this address, and connect to the server..?

Turns out I can!

I just go to the address bar and type localhost:7342 and the code is no longer hanging after the `.accept`.

The browser is stuck on the β€œloading page” screen: Image
On the other hand, I can play with the socket in my REPL:

>>> client_socket
<socket.socket fd=608, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 7342), raddr=('127.0.0.1', 60148)>

Whatever that means 😁
Then I thought β€œcan I send stuff back to the browser?”...

So I tried doing the obvious thing: calling a β€œsend” method on the socket.

I just got it wrong the first time: we need to send bytes.

Makes sense: sockets are low-level.

The result (13) is the length of what's sent. Image
When I did that, Firefox changed its look, and the message on the bottom-left now says the browser is transferring data.

I'm using Firefox, though.

Other browsers react differently.
Chrome just screams at me, saying the response was invalid.

We're onto something! I think... ImageImage
So, I went to take a shower (I had only played with Firefox up until that time) and it hit me:

Maybe I need to read the browser request first!
I tried calling the method `.read` on the socket, but turns out that doesn't exist.

Then, I just used the built-ins `dir` and `help`: Image
So, I reset everything, and I tried using `recv` before sending anything back.

That did it!

By reading the data in, first, and sending after, I got Firefox to display my β€œHello, world!” message! ImageImage
Chrome doesn't do the same thing, it still complains about my invalid response...

What this probably means is that the browser expects a message in a given format, and I'm not respecting that format...

We'll try to circle back to this, but now, I should keep reading the HOWTO!
Alright, just 1 more test.

To see if I was disrespecting the message format(s), I tried sending a proper snippet of HTML to Firefox.

Firefox doesn't render the HTML, it just shows it, which means I _will_ have to find out the proper format to talk to the browser. ImageImage
So, I created a server socket and connected to it (without doing anything useful)...

Can I create a client socket from the REPL and use it to talk to the server?

Probably I can!

Let's keep going πŸš€
I know I said I was going to try and create a client socket, but someone lent me a helping hand πŸ‘‡

As per this tweet, I need to include that meta information in the beginning of the message I send to the browser, so let's do just that...

I created a variable `msg` with the text I wanted to send, and I tried sending it.

The Firefox tab turned white, this time, but it didn't display my β€œHello, world!” message... ImageImage
Turns out I needed an empty line between the header info and the data itself!

Restarting everything, and inserting that new line in the message to send, it worked πŸ₯³πŸŽ‰πŸ₯³

Ok, NOW I'll read about the client sockets 😜 ImageImage
The HOWTO gives me code to create a client socket, and it's just two lines of code.

Because I'm trying to connect to a website, I'll try using the socket to request the home page of that website.

I googled what headers I must have on my request, but the response gives a 301... Image
The issue?

python.org uses HTTPS, and I'm trying to use HTTP.

Looking for a website that uses HTTP, I found ptsv2.com.

Replacing the host when connecting the socket and in the Host header means I get to request the page successfully!

Hooray πŸŽ‰πŸ₯³ Image
Really cool, right?

Next up, I want to connect my own server socket to my own client socket, and have them communicate.

For that, I'll have two REPLs open, side by side, and I'll be calling the `.send` and `.recv` methods on both sides, to see the data flow 😁

Let's gooo πŸš€
Ok, after all the gymnastics I had to do with the previous experiments, this turned out to be easier than I expected.

In fact, it's just me putting together the two halves of the puzzle, which means I'm in control of everything!

Here is how to do it πŸ‘‡

Today I learned so much about sockets, I thought it wouldn't make sense to _not_ write a short TIL blog article about sockets.

Here it is πŸ‘‡
mathspp.com/blog/til/019

I will stop for now, and I'll come back to sockets tomorrow!

Now, I gotta rest πŸ’€
See you tomorrow πŸ‘‹
Alright, it's time to keep experimenting!

I skimmed through a couple of other articles (I'll get back to that) but I also did an experiment that I think is SO cool...

I connected my phone and my laptop to one another, and had them communicate, with sockets!
This is much easier to do than what it sounds!

In fact, it's pretty similar to using sockets to get two instances of Python communicating (seen below πŸ‘‡)

The only difference is that we need to open the server to the β€œoutside world”.

So, the first thing we do, is open the server in the computer.

We ask the computer for the host name, so that we can connect from our phone.

Also, very important, your computer β€œmust be discoverable in the network”, which probably means changing a wifi setting (temporarily) ImageImage
Now, we want to create the socket client on our phone.

You need Python on your phone for this, I use QPython (play.google.com/store/apps/det…)

We create the socket as usual, but then connect to the host name the computer printed, instead of "localhost".

And then, send something! Image
That's it!

Now, I just have to receive the message on the computer!

Here's a picture proving it happened 😁

Take a look at the bottom of the two interpreters!

One sent the msg, the other received it 😁

I feel like a child πŸ˜…πŸ˜‚ Image
At this point, I've seen enough to start understanding what server sockets really do.
(I think)

The client socket seems to be responsible for sending and receiving data, while the server socket seems to be responsible for accepting connections
_and_ creating _client_ sockets.
There's an interesting nuance to sockets...

How can I know that I received the whole message?

The HOWTO I'm reading gives 4 options:

πŸ‘‰ fixed length msgs
πŸ‘‰ delimited msgs
πŸ‘‰ msgs indicate their length in the beginning
πŸ‘‰ sockets are single-use only

Here's a basic overview πŸ‘‡ ImageImageImageImage
Of course, all these methods have some gotchas and the dummy code I shared above isn't as robust as it should be!

It's just a basic rendition of each method.

(For the snippets above, the set up of the client and server sides was this πŸ‘‡)

β€’ β€’ β€’

Missing some Tweet in this thread? You can try to force a refresh
γ€€

Keep Current with Rodrigo πŸπŸ“

Rodrigo πŸπŸ“ Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @mathsppblog

31 Dec 21
Every day is a great day to start learning Python 🐍.

However, the new year is about to start.
Make good use of that extra motivation. πŸ’ͺ

Here is some of my best Python 🐍 content to help you out:
Want to learn about list comprehensions?

I have a comprehensive thread and a free cheatsheet for you.

(πŸ‘† see what I did there? My puns are fantastic!)

Here is the thread:

And here is the link to the free cheatsheet:

mathspp.gumroad.com/l/cheatsheet_l…
Read 12 tweets
29 Dec 21
Here is a countdown of my 5 best Python 🐍 articles of the year πŸ‘‡πŸ§΅

How many of them did you read?

mathspp.com/blog
Number 5.

There is my Pydon't article about Python 🐍's pass by value vs pass by reference vs pass by assignment behaviour.

πŸ”— mathspp.com/blog/pydonts/p…
Number 4.

In 4th place is an article that I published less than a month ago, so it's quite cool that it got so much visibility.

It's an article in which I analysis multiple solutions to a programming challenge from Advent of Code.

πŸ”— mathspp.com/blog/advent-of…
Read 7 tweets
25 Nov 21
I enjoy thinking about multiple possible solutions to the same Python 🐍 problems.

I do!

Call me crazy πŸ€ͺ, I don't care!

In the past, I've tweeted simple challenges πŸ†, you tweeted solutions, and I wrote a thread analysing your solutions.

Here is a meta 🧡 of past challenges!
The first challenge I ever posted was to implement the Caesar cipher

This is the thread with the solutions πŸ‘‡

The moral of the story was that very little people know about the `str.maketrans` and `str.translate` methods.

Read 21 tweets
25 Nov 21
Want to boost your Python 🐍 problem-solving skills?

I am looking for highly-motivated individuals that want to stay ahead of the curve!

If that's you, keep on reading πŸ‘‡...

Because tomorrow I'm launching the Python Problem-Solving Bootcamp!
This is a bootcamp focused on writing code.

Throughout the bootcamp you will solve 50 programming puzzles over the course of 25 days.

By going through the puzzles, you'll be practising your Python skills, and writing code is the best way to improve!

But there's more to it.
You will be getting 2 challenges/day.

Does that sound scary?

Good! If it does, then it's because it is an excellent growing opportunity.
Read 13 tweets
21 Nov 21
I have been tweeting about Python 🐍 string formatting.

I have been preaching πŸ™ that f-strings are the best string formatting alternative.

Then comes the string method `.format`.

And only then, %-formatting.

Here is a thread 🧡 comparing the 3 πŸ‘‡
In its most basic form,

πŸ‘‰ %-formatting uses % and a letter inside the string
πŸ‘‰ `.format` replaces sequences of {} with the data
πŸ‘‰ f-strings use {} to insert the data _inside_ the string

Here is how it looks like πŸ‘‡
An undervalued feature of string formatting is that you can easily determine whether your data should be formatted with its string (str) or with its representation (repr).

For debugging, `repr` is usually more useful.

Here is how this looks like πŸ‘‡
Read 10 tweets
6 Nov 21
The Python 🐍 Standard Library is one of the reasons I love πŸ’™ Python.

πŸ“‚πŸ” dealing with your filesystem is super simple.

All you have to do is use the `pathlib` module.

This short thread is a mini `pathlib` cookbook 🍳, showing some example usages of `pathlib`.

Ready πŸš€?
πŸ“‚ Creating a `Path` object

`Path` objects are the bread and butter of `pathlib`.

Here, I just create a path with no arguments, which defaults to the path `.`

Notice how I used `Path` but I get a `WindowsPath` back.

`pathlib` automatically detects your OS πŸ˜‰
πŸ“‚ Getting the parent

The `parent` attribute returns the logical parent of the path you have at hands πŸ‘‡
Read 11 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(