Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Python  Module 16 – Practical Python: text, CLIs, web, automation and security

Socket programming basics: TCP and UDP

Open TCP clients and servers with Python's socket module, read whole messages despite partial reads, set timeouts, and see when UDP or HTTP fits better.

  • Advanced
  • 20 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 8 of 20 minutes free
Free: A TCP server listens, a client connects, and both send bytes · recv() returns what has arrived, not a message · Every wait gets a time limit, and every socket gets closed · Practise: read whole messages from a stream that splits them. With a pass: 2 in-depth parts and 3 interview answers, about 12 minutes.

What you will learn

  • Create a TCP server and client with create_server() and create_connection()
  • Read a whole message despite partial reads, with a loop and a framing rule
  • Limit every blocking call with a timeout, and close sockets with a with statement
  • Send and receive UDP datagrams, and handle a datagram that never arrives
  • Choose between raw sockets, asyncio streams and HTTP for a program

Before you start

What you’ll learn · Before you start

What you will learn

  • Create a TCP server and client with create_server() and create_connection()
  • Read a whole message despite partial reads, with a loop and a framing rule
  • Limit every blocking call with a timeout, and close sockets with a with statement
  • Send and receive UDP datagrams, and handle a datagram that never arrives
  • Choose between raw sockets, asyncio streams and HTTP for a program

Before you start

On this page

One 7-byte word sent over a TCP One end of a network connection as a program sees it: an object with methods such as send() and recv(). Python's socket module makes TCP sockets, which carry a stream of bytes, and UDP sockets, which carry datagrams. can reach recv(1024) as 7 bytes at once or as seven calls of 1 byte each: TCP delivers a stream of bytes, not messages. That fact, a time limit on every wait and a clean close are most of what makes socket code work outside a test.

Python’s socket module gives you both ends. socket.create_server() opens a server socket that listens on an address and a port, socket.create_connection() connects a client, and a with statement closes each of them. You will run a TCP echo server, read whole messages from a stream that splits them, and limit every wait. The browser runner cannot open sockets, so the network examples were recorded on 127.0.0.1, this computer’s own address.

A TCP server listens, a client connects, and both send bytes

A TCP server uses two kinds of socket: one that listens on a port, and a new one for every connection it accepts. Step through the first client of echo.py:

Interactive · message by message One TCP connection, from listen to close Step through the first client of echo.py. The server has two sockets, one that listens and one for each connection it accepts.
One TCP connection, from listen to close, step 6 of 6. Messages so far: Client socket to Listening socket: connect; Listening socket to Connection socket: accept(); Client socket to Connection socket: sendall(b'namaste'); Connection socket to Client socket: sendall(b'NAMASTE'); Client socket to Connection socket: close.Client socketcreate_connection()Listening socketlisteningConnection socketrecv() returned b""connectaccept()sendall(b'namaste')sendall(b'NAMASTE')close

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The server listens. create_server(("127.0.0.1", 0)) binds a socket to a free port of this machine and listens. It accepts connections; it never carries data itself.
  2. The client connects. create_connection(("127.0.0.1", port), timeout=5) connects to that port. The operating system completes TCP's handshake before accept() even returns.
  3. accept() makes a new socket. accept() returns a new socket for this one connection, with the client's address. The listening socket goes back to waiting for the next client.
  4. Bytes in. The client calls sendall(b"namaste"). The connection socket's recv(1024) returns the 7 bytes; TCP delivers them in order, with no message boundaries of its own.
  5. Bytes out. The server sends the bytes back in capitals with sendall(). The client reads exactly 7 bytes, looping until they have all arrived.
  6. The client closes. Leaving the client's with block closes its socket. The server's next recv() returns b"", the sign that the other side has gone, and its loop ends.

A TCP echo server and two clients on 127.0.0.1 Python · tcp/echo.py
"""A TCP echo server and two clients on 127.0.0.1: listen, accept, send, receive and close."""
import socket
import threading

events = []                                      # the server's side, printed once the clients are done


def recv_exactly(sock, n):
    """Read exactly n bytes: recv() returns what has arrived, which may be less."""
    data = b""
    while len(data) < n:
        chunk = sock.recv(n - len(data))
        if not chunk:
            raise ConnectionError("the peer closed before the whole reply arrived")
        data += chunk
    return data


def serve(listener):
    for _ in range(2):                           # two clients, one after the other
        conn, (host, _port) = listener.accept()  # a new socket for this connection only
        with conn:
            events.append(f"accepted a connection from {host}")
            while data := conn.recv(1024):       # b"" means the client has closed its side
                events.append(f"received {data!r}")
                conn.sendall(data.upper())
            events.append("recv() returned b'': the client has gone")


with socket.create_server(("127.0.0.1", 0)) as listener:   # port 0: the system picks a free port
    port = listener.getsockname()[1]
    server = threading.Thread(target=serve, args=(listener,))
    server.start()
    for word in [b"namaste", b"vanakkam"]:
        with socket.create_connection(("127.0.0.1", port), timeout=5) as client:
            client.sendall(word)
            print(f"client sent {word!r}, got {recv_exactly(client, len(word))!r}")
    server.join()
print("server:", *events, sep="\n  ")

Output

client sent b'namaste', got b'NAMASTE'
client sent b'vanakkam', got b'VANAKKAM'
server:
  accepted a connection from 127.0.0.1
  received b'namaste'
  recv() returned b'': the client has gone
  accepted a connection from 127.0.0.1
  received b'vanakkam'
  recv() returned b'': the client has gone

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 echo.py

The server bound to 127.0.0.1, the The address 127.0.0.1 (::1 in IPv6) that always means this computer. A server bound to it accepts connections only from programs on the same machine., so only programs on this computer could connect, and port 0 let the system pick a free A number from 1 to 65535 that, with the address, names one listening program on a computer, such as 443 for HTTPS.. accept() returned a new socket for each client, while the listening socket went on waiting. sendall() sends every byte or raises, unlike send(), which may send only part and returns how much. When recv() returns b"", the other side has closed its end, and the documentation states it plainly: a returned empty bytes object indicates that the client has disconnected.

Key idea

A server listens with one socket and talks to each client on a new one; recv() returning b"" means the other side has closed.

Checkpoint

Check: TCP servers, clients and accept()

  1. Question 1 of 2 What does listener.accept() return in echo.py?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: A new socket for that one connection, and the client's address

    A TCP server has one listening socket and one connection socket per client. echo.py accepted two clients, each on a socket of its own.

  2. Question 2 of 2 In the server loop of echo.py, conn.recv(1024) returns b"". What has happened?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The client has closed its side of the connection

    b"" from recv() is the end of the stream: the peer closed, and no more data will ever come on this connection.

recv() returns what has arrived, not a message

A message sent with one sendall() can arrive in several pieces, and two messages can arrive in one. RFC 9293 says that TCP segments often do not correspond one for one to the send calls of the application, so the receiver gets a stream of bytes with no mark where one send ended. Step through a read of the 5-byte message hello behind a 2-byte length, which arrives in three chunks. The list chunks stands for what three recv() calls would return:

Interactive · line by line Reading a length-prefixed message that arrives in three chunks The message is b"hello" behind a two-byte length. It arrives as b"\x00", b"\x05he" and b"llo". Watch how often a recv() finds less than a whole message.

Program · trace/partial_reads.py

chunks = [b"\x00", b"\x05he", b"llo"]      # what three recv() calls return: TCP split the message
received = b""
size = None                                  # the length prefix is not known yet
while size is None or len(received) < 2 + size:
    received += chunks.pop(0)                # recv() returns whatever has arrived
    if size is None and len(received) >= 2:
        size = int.from_bytes(received[:2])  # the prefix is complete: the message length is known
print("length prefix:", size)
print("message:", received[2:2 + size])

Variables

After line 9: chunks is []; received is b'\x00\x05hello'; size is 5.chunksreceivedb'\x00\x05hello'size5
  • changed in this step

Printed so far

length prefix: 5
message: b'hello'

Every step was recorded from a run with Python 3.14.8 on macOS 26 arm64.

The drawing shows the variables when the program ends, and the program's 17 steps are listed below.

Line run 9
Next line end
Loop pass –
Every step as text
  1. Start. No line has run yet, so there are no variables. Python starts with line 1.
  2. Line 1. chunks = [b"\x00", b"\x05he", b"llo"] makes chunks a list of 3 items.
  3. Line 2. received = b"" sets received to b''.
  4. Line 3. size = None sets size to None.
  5. Line 4. while size is None or len(received) < 2 + size: tests its condition: it is true (size is None and received is b''), so the body runs.
  6. Line 5. received += chunks.pop(0) changes received from b'' to b'\x00'. Key point The first recv() finds only b"\x00": one byte, although the length prefix alone is two. That is normal for TCP, not an error.
  7. Line 6. size is None and len(received) >= 2 is false (size is None and received is b'\x00'), so Python skips the block under if size is None and len(received) >= 2:.
  8. Line 4. while size is None or len(received) < 2 + size: tests its condition: it is true (size is None and received is b'\x00'), so the body runs again (pass 2).
  9. Line 5. received += chunks.pop(0) changes received from b'\x00' to b'\x00\x05he'.
  10. Line 6. size is None and len(received) >= 2 is true (size is None and received is b'\x00\x05he'), so the block under if size is None and len(received) >= 2: runs.
  11. Line 7. size = int.from_bytes(received[:2]) sets size to 5 (it was None). Now received holds b"\x00\x05he". The bytes \x00\x05 are the number 5 in big-endian order, so the message that follows is 5 bytes long, and only 2 of them are here.
  12. Line 4. while size is None or len(received) < 2 + size: tests its condition: it is true (size is 5 and received is b'\x00\x05he'), so the body runs again (pass 3).
  13. Line 5. received += chunks.pop(0) changes received from b'\x00\x05he' to b'\x00\x05hello'. The third recv() brings b"llo". With the 2-byte prefix and 5 bytes of message, received holds 7 bytes, so the loop test is false at last.
  14. Line 6. size is None and len(received) >= 2 is false (size is 5 and received is b'\x00\x05hello'), so Python skips the block under if size is None and len(received) >= 2:.
  15. Line 4. while size is None or len(received) < 2 + size: tests its condition: it is false (size is 5 and received is b'\x00\x05hello'), so the loop ends.
  16. Line 8. print("length prefix:", size) prints length prefix: 5.
  17. Line 9. print("message:", received[2:2 + size]) prints message: b'hello'. That was the last line, so the program ends. Three recv() calls, and none returned a whole message. A program that took one recv() as one message would have parsed half of it.

The loop could not know the length of the message until the second chunk had brought the whole prefix, and it went on reading until it held all 7 bytes. recv_exactly() in echo.py is the same loop as a function: it asks each time only for the bytes still missing, and treats b"" as the connection closing in the middle. Every protocol over TCP also needs framing: The rule a protocol uses to mark where each message ends in a stream of bytes, such as a newline after each message or a length before it. TCP keeps no record of where one write ended, so every protocol over it needs one. More in “Networking with asyncio streams”, a rule for where a message ends: a newline after each message, or a length prefix: A fixed-size number written before each message that gives its size in bytes, often 4 bytes in big-endian order. The receiver reads the number, then exactly that many bytes, whatever they contain. More in “Networking with asyncio streams” before it, as here.

One recv() taken as one message

data = sock.recv(1024) followed by json.loads(data) works on your laptop, where short messages usually arrive whole, and fails under load or over a slow network with half a message. Read with a loop until your framing says the message is complete.

Checkpoint

Check: Partial reads and framing

  1. Question 1 of 2 The server sent 1,000 bytes with one sendall(). What may the client's sock.recv(1024) return?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Any number of bytes from 1 to 1,000, whatever has arrived

    RFC 9293 notes that TCP segments often do not correspond one for one to the application's send calls, so code reads in a loop until it has what its framing promised.

  2. Question 2 of 2 Why does every protocol over TCP need framing, such as a newline or a length prefix?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Because TCP keeps no record of where one sendall() ended and the next began

    A length prefix such as the two bytes \x00\x05 in the traced run tells the receiver how many bytes to read next; a newline tells it where to stop.

Every wait gets a time limit, and every socket gets closed

By default a socket waits for ever: a peer that accepts a connection and then sends nothing holds recv() until the program is stopped. settimeout(seconds) limits every blocking call on the socket, and the timeout argument of create_connection() sets the same limit from the start. Since Python 3.10, socket.timeout is an alias of TimeoutError. This run uses a connected pair of sockets inside one program, which needs no network:

A silent peer, a closed peer, and the with statement Python · tcp/timeouts.py
"""Timeouts and closing, on a connected pair of sockets: a silent peer, a closed peer, and the with statement."""
import socket
import time

left, right = socket.socketpair()      # two connected sockets in this program, so no network is needed
with left, right:
    left.settimeout(0.2)               # every blocking call on left now waits at most 0.2 s
    start = time.monotonic()
    try:
        left.recv(1024)                # right never sends anything
    except TimeoutError as e:
        print(f"silent peer: {type(e).__name__} ({e}) after {time.monotonic() - start:.1f} s")
    right.close()                      # the peer closes its end
    print("closed peer: recv() returned", left.recv(1024))
print("after the with block, left is closed:", left.fileno() == -1)

Output

silent peer: TimeoutError (timed out) after 0.2 s
closed peer: recv() returned b''
after the with block, left is closed: True

This output changes from run to run: the wait is measured on each run and may take a little longer than 0.2 s on a busy computer

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 timeouts.py

The with block closed both sockets on the way out, as it would after an exception, and a closed socket reports fileno() as −1. Five more tools come up as soon as programs talk for real:

  • Framing choices: newline-ended messages are simple but break on a message that contains a newline; a length prefix carries any bytes but needs a size limit.
  • Half-close: shutdown(SHUT_WR) says that you have sent everything, while the socket can still read the answer.
  • Binding: 127.0.0.1 keeps a server to this machine, '' opens it on every interface, and one address and port take one server.
  • UDP: a SOCK_DGRAM socket sends single One self-contained message sent by UDP. It arrives whole or not at all, and datagrams may be lost, repeated or delivered in another order. that keep their boundaries but may be lost. UDP needs no connection and no accept(), so one socket can hear many senders, and the program must cope with loss itself.
  • Higher levels: HTTP clients and asyncio streams do this work for you, and most programs should use them. HTTP fits any service that already speaks it, such as a web API, and asyncio streams fit a TCP protocol of your own that keeps many connections open.
Port Number Lookup Look up which service a port number usually belongs to before you choose one for a server.

Key idea

Give every socket a timeout and a with block, so that a silent peer cannot hold the program and every path closes the socket.

Checkpoint

Check: Timeouts and closing

  1. Question 1 of 2 After sock.settimeout(5), the peer sends nothing for 5 seconds. What does sock.recv(1024) do?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: It raises TimeoutError

    With a timeout, a silent peer turns into a TimeoutError that the program can handle, as the run printed after about 0.2 seconds.

  2. Question 2 of 2 An exception is raised inside a block that starts with socket.create_connection(...) as s. What happens to s?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: It is closed as the with block exits, and the exception goes on

    Exiting the context manager is equivalent to calling close(), the documentation says, so a with block closes the socket even when the code inside fails.

Practise: read whole messages from a stream that splits them

Write recv_exactly() and recv_line(). The sample tests use a fake socket that returns from 1 to 5 bytes at a time, chosen by a seeded random generator, so your loops meet the same splits on every run. Once they pass, a practice session starts from your weakest concept, and each answer is explained as soon as you give it.

Exercise · Medium · Python

Read whole messages from a stream that splits them

Write two functions in netio.py that read from anything with a recv(n) method, as a socket has. The tests pass in a fake socket that returns a random number of bytes, from 1 to 5, on each call, as a real network may, and b"" once its data has run out, as a closed connection does.

**recv_exactly(sock, n)** returns exactly n bytes. It calls recv() again until it has them all, asking each time only for the bytes still missing, and raises ConnectionError when recv() returns b"" before that. recv_exactly(sock, 0) returns b"".

**recv_line(sock, limit=1024)** returns the bytes up to and including the first b"\n". It must not read past the newline, so that the next call finds the next line. It raises ValueError when limit bytes have arrived without a newline, and ConnectionError when the connection closes first.

Starter code · netio.py

def recv_exactly(sock, n):
    """Exactly n bytes from sock; ConnectionError if it closes first."""
    return sock.recv(n)


def recv_line(sock, limit=1024):
    """The bytes up to and including the first newline; ValueError past limit, ConnectionError if it closes."""
    return sock.recv(limit)
The sample tests · test_netio.py
import random

from netio import recv_exactly, recv_line


class ChunkySocket:
    """Returns from 1 to 5 bytes per recv(), chosen by a seeded random generator, then b"" when the data runs out."""

    def __init__(self, data, seed=7):
        self.data, self.rng, self.calls = data, random.Random(seed), 0

    def recv(self, n):
        self.calls += 1
        size = min(n, self.rng.randint(1, 5))
        part, self.data = self.data[:size], self.data[size:]
        return part


class OneThenAsked:
    """The first recv() returns one byte, every later one as many as it is asked for."""

    def __init__(self, data):
        self.data, self.first = data, True

    def recv(self, n):
        size = 1 if self.first else n
        self.first = False
        part, self.data = self.data[:size], self.data[size:]
        return part


def raises(error, call, *args):
    try:
        call(*args)
    except error:
        return True
    return False


def test_exactly_collects_small_chunks():
    """recv_exactly() keeps calling recv() until it has n bytes"""
    sock = ChunkySocket(b"0123456789abcdef")
    assert recv_exactly(sock, 10) == b"0123456789"
    assert recv_exactly(sock, 6) == b"abcdef"
    assert sock.calls > 2


def test_exactly_asks_only_for_the_missing_bytes():
    """recv_exactly() never takes a byte of the next message"""
    sock = OneThenAsked(b"abcdefgh")
    assert recv_exactly(sock, 4) == b"abcd"
    assert sock.data == b"efgh"


def test_exactly_zero_and_early_close():
    """zero bytes need no read, and a close before n bytes is an error"""
    assert recv_exactly(ChunkySocket(b"abc"), 0) == b""
    assert raises(ConnectionError, recv_exactly, ChunkySocket(b"abc"), 5)


def test_line_stops_at_the_newline():
    """recv_line() returns one line, and the next call returns the next"""
    sock = ChunkySocket(b"ROLL 21\nROLL 22\n")
    assert recv_line(sock) == b"ROLL 21\n"
    assert recv_line(sock) == b"ROLL 22\n"


def test_line_limit_and_close():
    """too long without a newline, or closed first, is an error"""
    assert raises(ValueError, recv_line, ChunkySocket(b"x" * 50), 20)
    assert raises(ConnectionError, recv_line, ChunkySocket(b"no newline"))
A hint

In recv_exactly(), keep a bytes buffer and loop while len(buf) < n, calling sock.recv(n - len(buf)). recv_line() can then read one byte at a time with recv_exactly(sock, 1), which can never take a byte of the next line.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Practice that adapts to you

Practise this lesson

9 questions about 8 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 9 What does the port 0 in create_server(("127.0.0.1", 0)) mean?

    Choose one answer.

    Show the answer: Question 1 of 9

    Answer: The system picks a free port, which getsockname() then reports

    Port 0 is a request for a free port; tests use it so that two runs never clash.

  2. Question 2 of 9 Why does echo.py use sendall() rather than send()?

    Choose one answer.

    Show the answer: Question 2 of 9

    Answer: send() may send only part of the data and returns how much; sendall() sends every byte or raises

    The documentation says applications using send() are responsible for checking that all data has been sent; sendall() does that loop for you.

  3. Question 3 of 9 Why does the server keep its listening socket open while it talks to the first client?

    Choose one answer.

    Show the answer: Question 3 of 9

    Answer: So that it can accept the next client, since each connection has a socket of its own

    The listening socket only produces connection sockets. A server that serves many clients keeps it open and hands each connection to a loop, a thread or a task.

  4. Question 4 of 9 Why does recv_exactly() call sock.recv(n - len(data)) rather than sock.recv(n)?

    Choose one answer.

    Show the answer: Question 4 of 9

    Answer: So that it never reads past the end of this message into the next one

    A reader that takes more than its message leaves the next one without its first bytes.

  5. Question 5 of 9 In the traced run, how many recv() calls did the loop make in all, to read the 2-byte prefix and the 5-byte message?

    Type a number.

    A hint

    The bytes arrived as b"\x00", b"\x05he" and b"llo", and each pass of the loop is one call.

    Show the answer: Question 5 of 9

    Answer: 3 calls

    The first call returned one byte of the prefix, the second the other byte of the prefix and the first two bytes of the message, and the third the last three bytes: three passes of the loop, three calls, and not one of them returned a whole message.

  6. Question 6 of 9 A client does json.loads(sock.recv(4096)). It passes its tests and fails in production with JSONDecodeError on long messages. Why?

    Choose one answer.

    Show the answer: Question 6 of 9

    Answer: Long messages arrive in more than one piece, so one recv() returns only part of the JSON

    Read until the framing says the message is complete, for example a length prefix and recv_exactly(), then parse.

  7. Question 7 of 9 In Python 3.14, what is socket.timeout?

    Choose one answer.

    Show the answer: Question 7 of 9

    Answer: An alias of TimeoutError

    Catch TimeoutError; socket.timeout is the same class under an older name.

  8. Question 8 of 9 What does the timeout=5 of socket.create_connection((host, port), timeout=5) apply to?

    Choose one answer.

    Show the answer: Question 8 of 9

    Answer: The connection attempt, and every later blocking call on the socket

    The documentation says the timeout is set on the socket instance before attempting to connect, so every blocking call on it is limited.

  9. Question 9 of 9 A server reads from each client without a timeout, one client at a time. A client connects and sends nothing. What happens, and what is the fix?

    Choose one answer.

    Show the answer: Question 9 of 9

    Answer: That recv() waits for ever and no other client is served; set a timeout and close idle connections

    Every blocking read needs a limit. Servers also need more than one connection at a time, with threads, selectors or asyncio, so that one slow client cannot hold the rest.

Framing messages, closing cleanly and binding with care Pro: opens with a Pro, Premium or Ultimate pass

A protocol over TCP needs more than a reading loop: a rule for where each message ends, a way to say that you are done, and a decision about who may connect at all. This part puts two framings on one stream and shows where each one breaks, half-closes a connection, and binds a server with care.

In this part:

  • Two framings on one stream, and the limit each one needs
  • Half-close: a shutdown ends the request, not the connection
  • Binding: free ports, ports in use and who can connect

3 runnable examples (Python) · about 7 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

UDP datagrams, and choosing the right level for a program Pro: opens with a Pro, Premium or Ultimate pass

UDP drops the stream: each send is one datagram, delivered whole or not at all, so the program has to handle what TCP would have handled for it. This part runs a UDP client that survives a lost datagram, works out what a retry is worth, and ends with a decision table for choosing between sockets, asyncio streams and HTTP.

In this part:

  • A UDP ping that survives a lost datagram
  • Raw sockets, asyncio streams or HTTP: a decision with reasons

1 runnable example (Python) · about 8 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Interview questions

  1. Fresher to mid · Warm-up

    What is the difference between a TCP socket and a UDP socket in Python?

    A TCP socket (SOCK_STREAM) carries a connection: a server listens and accepts, each client gets a socket of its own, and the bytes arrive in order or the program gets an error. It is a stream with no message boundaries, so one send may arrive in several recv() calls and two sends in one, and the program reads until its own framing says that a message is complete. A UDP socket (SOCK_DGRAM) has no connection: each sendto() is one datagram, which keeps its boundaries but may be lost, repeated or reordered, and nobody tells the sender. Choose TCP when every message counts, and UDP when a lost message does no harm or the protocol is already UDP.

  2. Fresher to mid

    A client sends JSON messages over TCP and reads each reply with one recv(4096) followed by json.loads(). It passes every test on a laptop but now and then fails in production with half a message or extra data. Explain why, and rewrite the reading.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  3. Mid to senior

    A TCP server accepts one client at a time and reads from it until it closes. Once a day it stops answering everyone, although the process is alive and the CPU is idle. Find the cause, fix the server, and describe the test that would have shown it.

    Model answer, Pro. First step and follow-ups

  4. Mid to senior

    An app sends one UDP datagram per event to a metrics collector. At peak hours the dashboards show 15 % fewer orders than the database does, and no errors appear anywhere. Explain what is happening and what you change.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • A TCP server listens with create_server(), accept() returns a new socket per client, and recv() returning b"" means the other side has closed.
  • recv() returns what has arrived, so read in a loop until your framing, a newline or a length prefix, says the message is complete.
  • Give every socket a timeout and a with block, so that a silent peer cannot hold a program and a socket is closed on every path.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.