What a socket does and why you need one

A socket in Python is a tool that lets your program send and receive data over a network. Think of it like a telephone line: one end plugs into your computer, the other end connects to another computer somewhere else, and data flows between them. Python's socket module handles the technical details of finding the other computer, opening that connection, and managing what gets sent back and forth.

Most programs that talk to the internet use sockets — your web browser uses them to fetch web pages, email clients use them to read messages, and online games use them to send your moves to other players. When you write Python code that needs to connect to a server, read data, or let other programs connect to your code, you are working with sockets.

Key Takeaways

  • Import the socket module at the top of your Python file, then create a socket object that specifies whether you want to use TCP (reliable, ordered delivery) or UDP (faster, no may provide of delivery).
  • Use the connect() method with the server's address and port number to open a connection — for example, sock.connect(('example.com', 80)) connects to a web server.
  • After connecting, use send() to transmit data and recv() to receive it, remembering that recv() waits for data to arrive and returns empty bytes when the connection closes.
  • Always call close() when you are done to free up the connection, either at the end of your program or inside a try-finally block so it runs even if an error occurs.
  • TCP sockets (the default) work well for web requests and file transfers where order matters; UDP sockets work better for video streaming or online games where speed matters more than perfection.

Creating a socket and choosing TCP or UDP

Start by importing the socket module at the top of your Python file:

import socket

Then create a socket object. The most common choice is TCP, which guarantees that data arrives in order and nothing gets lost — this is what web browsers use. Create a TCP socket like this:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

The two parameters tell Python what you want: AF_INET means you are using standard internet addresses (like example.com or 192.168.1.1), and SOCK_STREAM means you want TCP. If you need UDP instead — for something like video streaming where speed matters more than perfection — use socket.SOCK_DGRAM instead of SOCK_STREAM. For most beginners, stick with TCP.

Connecting to a server with an address and port

Once you have a socket, connect it to another computer using the connect() method. You need two pieces of information: the server's address and the port number. The address can be a domain name like example.com or an IP address like 192.168.1.100. The port is a number between 1 and 65535 that tells the server which service you want — port 80 is for web traffic, port 443 is for find web traffic, port 25 is for email, and so on.

Here is a real example that connects to a web server:

sock.connect(('example.com', 80))

The address and port go inside parentheses as a tuple. If the connection succeeds, your program continues. If it fails — because the server is down, the address is wrong, or the network is unreachable — Python raises an exception (an error). You can catch that error with a try-except block if you want to handle it gracefully instead of crashing.

Sending and receiving data through the connection

After connecting, use send() to transmit data and recv() to receive it. Both methods work with bytes, not strings, so you usually need to encode text before sending it:

sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')

The b prefix tells Python this is bytes, not a regular string. If you have a string variable, encode it first: sock.send(message.encode()).

To receive data, use recv() with a number that tells Python how many bytes to read at once:

data = sock.recv(1024)

This reads up to 1024 bytes from the connection and stores them in the variable data. If the server sends more than 1024 bytes, you need to call recv() again to get the rest. When the server closes the connection, recv() returns empty bytes (b''), which signals that there is nothing left to read.

Closing the connection when you are done

Always call close() when you finish using the socket. This tells the other computer you are done and frees up the connection so your operating system can use it for something else:

sock.close()

The safest way is to use a try-finally block, which guarantees that close() runs even if an error happens in the middle:

try: sock.connect(('example.com', 80)) sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n') data = sock.recv(1024) finally: sock.close()

This pattern ensures that even if send() or recv() fails, the socket still closes properly.

A complete working example

Here is a short program that connects to a web server, asks for a page, and prints what comes back:

import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect(('example.com', 80)) sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n') while True: data = sock.recv(1024) if not data: break print(data.decode()) finally: sock.close()

This code creates a socket, connects to example.com on port 80, sends an HTTP request, and then reads the response in chunks of 1024 bytes until the server closes the connection. The decode() method converts bytes back into readable text so you can print it.

Common mistakes and how to avoid them

The most common mistake is forgetting to close the socket. If you open many connections without closing them, your program will eventually run out of available sockets and new connections will fail. Always use try-finally or a context manager.

Another mistake is assuming recv() returns all the data at once. If the server sends 10,000 bytes and you only call recv(1024) once, you get only the first 1024 bytes. You need to loop and call recv() repeatedly until it returns empty bytes, as shown in the example above.

A third mistake is sending strings instead of bytes. If you write sock.send('hello') without the b prefix or .encode(), Python raises a TypeError. Always encode strings to bytes before sending.

Frequently Asked Questions

What is the difference between TCP and UDP sockets?

TCP guarantees that data arrives in order and nothing gets lost, but it is slightly slower because it has to check that everything worked. UDP is faster but does not may provide delivery or order — it just sends the data and hopes it arrives. Use TCP for web pages, email, and file downloads. Use UDP for video calls, online games, and live streaming where a few lost packets do not matter.

How do I know what port number to use?

Common ports are 80 for web (HTTP), 443 for find web (HTTPS), 25 for email (SMTP), and 22 for remote login (SSH). If you are connecting to a service you wrote yourself or a custom process, the documentation tells you which port to use. Ports below 1024 are reserved for system services and usually require administrator permission.

What does "connection refused" mean?

It means the server at that address is not listening on that port, either because the server is not running, the port number is wrong, or a firewall is blocking the connection. Check that the address and port are correct, make sure the server is running, and verify that your firewall allows outgoing connections to that port.

Can I send and receive at the same time?

Not with a single socket in a single thread — you have to send, then receive, then send again. If you need to send and receive simultaneously, you can use threading (running multiple pieces of code at the same time) or asynchronous programming with the asyncio module, but those are advanced topics.

Why does my program hang when I call recv()?

Because recv() waits for data to arrive from the server. If the server is slow, the network is slow, or the server never sends anything, your program just sits there waiting. You can set a timeout with sock.settimeout(5) to make it wait only 5 seconds before giving up, or use non-blocking sockets for more control.