Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
The reliable pattern is simple: encode each screenshot as JPEG in memory, prefix it with a fixed-width length, send the header and payload with sendall(), and have the receiver loop until it has collected exactly that many bytes. JPEG quality controls the size–fidelity trade-off; the fastest setting for your application must be measured with representative screens because encoding CPU time, network time and visual quality all interact.
What makes screenshot sockets slow or unreliable?
A screenshot is usually a large uncompressed pixel buffer. Sending that buffer directly consumes bandwidth, while treating a TCP connection as if it preserved message boundaries can merge or split frames unpredictably. TCP provides an ordered byte stream, not individual messages. You therefore need two separate solutions:
- Compression: encode the image as JPEG before transmission.
- Framing: send the payload length first, then receive until that declared length has arrived.
JPEG is lossy, so it is appropriate when small visual differences are acceptable. Text-heavy interfaces can reveal ringing or blurred colored edges sooner than photographs. Test the actual screens your users will view.
Install Pillow and choose an image source
Install Pillow in the environment that captures or encodes the image:
#1 Best Overall
- 𝐇𝐢𝐠𝐡-𝐒𝐩𝐞𝐞𝐝 𝐔𝐒𝐁 𝐄𝐭𝐡𝐞𝐫𝐧𝐞𝐭 𝐀𝐝𝐚𝐩𝐭𝐞𝐫 - UE306 is a USB 3.0 Type-A to RJ45 Ethernet adapter that adds a reliable wired network port to your laptop, tablet, or Ultrabook. It delivers fast and stable 10/100/1000 Mbps wired connections to your computer or tablet via a router or network switch, making it ideal for file transfers, HD video streaming, online gaming, and video conferencing.
- 𝐔𝐒𝐁 𝟑.𝟎 𝐟𝐨𝐫 𝐅𝐚𝐬𝐭𝐞𝐫, 𝐌𝐨𝐫𝐞 𝐒𝐭𝐚𝐛𝐥𝐞 𝐃𝐚𝐭𝐚 𝐓𝐫𝐚𝐧𝐬𝐟𝐞𝐫𝐬- Powered via USB 3.0, this adapter provides high-speed Gigabit Ethernet without the need for external power(10/100/1000Mbps). Backward compatible with USB 2.0/1.1, it ensures reliable performance across a wide range of devices.
- 𝐒𝐮𝐩𝐩𝐨𝐫𝐭𝐬 𝐍𝐢𝐧𝐭𝐞𝐧𝐝𝐨 𝐒𝐰𝐢𝐭𝐜𝐡- Easily connect your Nintendo Switch to a wired network for faster downloads and a more stable online gaming experience compared to Wi-Fi.
- 𝐏𝐥𝐮𝐠 𝐚𝐧𝐝 𝐏𝐥𝐚𝐲- No driver required for Nintendo Switch, Windows 11/10/8.1/8, and Linux. Simply connect and enjoy instant wired internet access without complicated setup.
- 𝐁𝐫𝐨𝐚𝐝 𝐃𝐞𝐯𝐢𝐜𝐞 𝐂𝐨𝐦𝐩𝐚𝐭𝐢𝐛𝐢𝐥𝐢𝐭𝐲- Supports Nintendo Switch, PCs, laptops, Ultrabooks, tablets, and other USB-powered web devices; works with network equipment including modems, routers, and switches.
python -m pip install Pillow
Your capture code may return a Pillow Image, a PNG file, or another pixel format. The examples below accept a Pillow image. If the source contains transparency, decide what should replace it first; JPEG has no alpha channel.
Encode a screenshot as JPEG in memory
Use io.BytesIO to avoid a temporary file. Convert deliberately to RGB, because JPEG encoders expect a compatible color mode.
from io import BytesIO
from PIL import Image
def encode_jpeg(image: Image.Image, quality: int = 80, optimize: bool = True,
subsampling: int | str = "keep") -> bytes:
"""Return JPEG bytes for a Pillow image."""
if image.mode in ("RGBA", "LA") or "transparency" in image.info:
# Choose the background your product requires.
background = Image.new("RGB", image.size, "white")
rgba = image.convert("RGBA")
background.paste(rgba, mask=rgba.getchannel("A"))
image = background
else:
image = image.convert("RGB")
out = BytesIO()
save_args = {
"format": "JPEG",
"quality": quality,
"optimize": optimize,
}
if subsampling != "keep":
save_args["subsampling"] = subsampling
image.save(out, **save_args)
return out.getvalue()
Pillow documents quality from 0 to 95 (default 75) and cautions that values above 95 produce much larger files for little visual benefit. Its tutorial uses RGB conversion with quality=80, optimize=True as an example, not as a universal optimum (JPEG format options; Pillow tutorial).
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
What optimize=True changes
Optimization performs an additional encoder pass to select more efficient JPEG tables. It can reduce the payload, but it also consumes CPU. Keep it only when the saved transfer time outweighs that extra work on your machines.
Quality and subsampling
Compare several quality values, such as 60, 75, 80 and 90, using identical screenshots. Pillow defines subsampling 0, 1 and 2 as 4:4:4, 4:2:2 and 4:2:0 respectively (Pillow JPEG presets). Lower chroma resolution often saves bytes but can damage colored text and sharp UI edges. Inspect readability, not just file size.
Rank #2
- Connects a USB 3.0 device (computer/laptop) to a router, modem, or network switch to deliver Gigabit Ethernet to your network connection. Does not support Smart TV or gaming consoles (e.g.Nintendo Switch).
- Supported features include Wake-on-LAN function, Green Ethernet & IEEE 802.3az-2010 (Energy Efficient Ethernet)
- Supports IPv4/IPv6 pack Checksum Offload Engine (COE) to reduce Cental Processing Unit (CPU) loading
- Compatible with Windows 8.1 or higher, Mac OS
Use a length-prefixed TCP protocol
A minimal frame is 4-byte unsigned length | JPEG payload. Encode the length in network byte order with struct.pack("!I", length). The receiver must reject impossible lengths before allocating memory and treat a closed connection before the full payload as an incomplete frame.
Complete sender
import socket
import struct
import time
from PIL import ImageGrab
HOST = "127.0.0.1"
PORT = 5000
MAX_FRAME = 25 * 1024 * 1024
def encode_jpeg(image, quality=80, optimize=True):
from io import BytesIO
image = image.convert("RGB")
out = BytesIO()
image.save(out, format="JPEG", quality=quality, optimize=optimize)
return out.getvalue()
def send_frame(sock, payload: bytes) -> None:
if not 0 < len(payload) <= MAX_FRAME:
raise ValueError("JPEG payload exceeds configured limit")
sock.sendall(struct.pack("!I", len(payload)))
sock.sendall(payload)
with socket.create_connection((HOST, PORT), timeout=10) as sock:
while True:
started = time.perf_counter()
screenshot = ImageGrab.grab()
jpeg = encode_jpeg(screenshot, quality=80, optimize=True)
encode_ms = (time.perf_counter() - started) * 1000
send_frame(sock, jpeg)
print(f"encoded={encode_ms:.1f} ms bytes={len(jpeg)}")
time.sleep(0.1)
sendall() keeps sending until the complete buffer is sent or an error occurs. A single send() call may write only part of the buffer, so do not use it without your own loop. These semantics are documented by the Python 3.13 socket documentation.
Complete receiver
import socket
import struct
from io import BytesIO
from PIL import Image
HOST = "0.0.0.0"
PORT = 5000
MAX_FRAME = 25 * 1024 * 1024
def recv_exact(sock: socket.socket, count: int) -> bytes:
chunks = []
remaining = count
while remaining:
chunk = sock.recv(min(64 * 1024, remaining))
if not chunk:
raise ConnectionError("peer closed before the frame was complete")
chunks.append(chunk)
remaining -= len(chunk)
return b"".join(chunks)
def recv_frame(sock: socket.socket) -> bytes:
header = recv_exact(sock, 4)
(length,) = struct.unpack("!I", header)
if length == 0 or length > MAX_FRAME:
raise ValueError(f"invalid frame length: {length}")
return recv_exact(sock, length)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listener:
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind((HOST, PORT))
listener.listen(1)
conn, address = listener.accept()
with conn:
print("connected:", address)
while True:
jpeg = recv_frame(conn)
image = Image.open(BytesIO(jpeg))
image.load() # force decoding while bytes are present
image.save("latest.jpg") # replace with display or application logic
print(image.size, len(jpeg))
recv() can return fewer bytes than requested, including part of the four-byte header. The recv_exact loop handles both the header and payload. recv_into() is another option when you want to fill a preallocated buffer; it also receives up to the requested byte count.
Measure the setting instead of guessing
There is no universal quality, subsampling or frame-rate setting for this workload. Build a small test using the same capture source, machine and network conditions you will deploy.
| Metric | How to record it | Why it matters |
|---|---|---|
| JPEG bytes | len(jpeg) |
Determines bandwidth and buffering pressure |
| Encode time | Timer around image.save |
Shows CPU cost, including optimization |
| Socket transfer time | Timer around the two sendall calls |
Shows network and receiver back-pressure |
| Decode time | Timer around Image.open and load |
Captures receiver CPU cost |
| End-to-end latency | Timestamp capture through display/processing | Matches what the user experiences |
| Sustained frame rate | Count completed frames over a fixed interval | Reveals queue growth and dropped work |
Test text-heavy pages, flat-color dashboards and photographic content separately. Keep the screenshot set and network path identical while comparing quality and subsampling. A smaller file is not faster if encoding or decoding dominates.
Rank #3
- [Expansion Ports] The USB C to Ethernet Adapter expands the device to three USB 3.0 ports and one Gigabit Ethernet port. Provides you more peripheral ports while maintaining a stable network connection, plug and play, no driver required.
- [Gigabit Network Port] ALL-LUCKY USB Ethernet Adapter transmission rate up to 1000Mbps, also compatible with 10/100Mbps bandwidth. It allows you to enjoy a smooth and stable network connection and avoid too much lag. (Note: To reach 1Gbps, please use CAT6 or above Ethernet cable connection)
- [Convertible Connector]This usb hub with ethernet not only has USB-A connector, but also can be converted to USB-C connector, so that you can easily convert the connector according to the device port, improve the convenience of use.
- [High-Speed Data Transfer] The usb to ethernet adapter adopts USB 3.0 transmission technology, supports up to 5Gbps transmission rate, and is compatible with USB 2.0(480Gbps),USB 1.0(12Mbps), easily transfer video, files and other data for you in seconds. (Note: Maximum output current is 900mA, does not support charging devices.)
- [Widely Compatible]The usb c ethernet adapter for iMac, MacBook Pro, iPad Pro, XPS and many other devices. Compatible with Windows 11/10/8.1/8, Mac OS, iPad OS, Chrome OS.(Note: Driver is required on Win 7) It can be used in office, school, library and other occasions, compact and portable, easy to carry around.
Reliability, flow control and security
Prevent unbounded memory use
Set a maximum frame size on both ends and reject a declared length above it before collecting bytes. You can also impose socket timeouts so a peer cannot hold a connection indefinitely while sending a partial frame.
Handle disconnects and back-pressure
Catch TimeoutError, ConnectionError and OSError. Reconnect with a bounded backoff and decide whether to drop stale screenshots rather than queueing unlimited frames. For live previews, keeping the newest frame is often preferable to transmitting every historical frame.
Protect the connection
The example is plain TCP. On an untrusted network, add authentication and transport encryption (for example, TLS) and validate who may connect. Never trust a length prefix, image metadata or a requested output path.
Choose a protocol version
If the format may evolve, reserve a version or flags byte in a larger header. Document byte order, maximum length, JPEG parameters and what a clean shutdown means. A length prefix solves framing; it does not provide encryption, integrity authentication or message semantics.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting common failures
The receiver shows corrupted or merged images
Cause: it assumes one recv() equals one frame, or the sender omitted framing. Fix: send the four-byte length before every payload and use recv_exact for both header and body.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallRank #4
- The Anker Advantage: Join the 65 million+ powered by our leading technology.
- Instant Internet: Connect to the internet instantly from virtually any USB-C 3.0 device, and enjoy stable connection speeds of up to 1 Gbps.
- Lightweight and Compact: The space-saving and portable design measures just over half an inch thick and weighs about the same as a AA battery.
- Premium Build: Features a sleek aluminum exterior and braided-nylon cable to complement the design of high-end devices.
- What You Get: PowerExpand USB-C to Gigabit Ethernet Adapter, welcome guide, 18-month worry-free warranty, and friendly customer service.
Only part of a screenshot arrives
Cause: a partial send() or a disconnect. Fix: use sendall(), retain the length prefix, and treat EOF before the declared length as an incomplete frame.
cannot write mode RGBA as JPEG
Cause: JPEG does not store alpha. Composite the image over an intentional background, then convert to RGB before saving.
CPU usage rises after enabling optimization
optimize=True adds an encoder pass. Compare end-to-end latency and sustained frame rate with it disabled; retain it only when the smaller payload compensates for CPU time.
Frames become unreadable at a lower quality
Raise quality or use a less aggressive subsampling value, then measure the resulting bytes and latency. Colored labels and one-pixel UI lines are useful test cases.
Recommended Free Tools
The connection hangs
Check that the client and server agree on host, port, byte order and maximum length. Add timeouts, log the declared and received byte counts, and verify that both sides close or reuse the connection consistently.
Best Value
- COMPACT DESIGN - The compact-designed portable BENFEI USB A/C to Ethernet adapter connects your computer or tablet to a router,modem or network switch for network connection. It adds a standard RJ45 port to your Ultrabook, notebook or Macbook Air for file transferring, video conferencing, gaming, and HD video streaming.
- SUPERIOR STABILITY - Built-in advanced IC chip works as the bridge between RJ45 Ethernet cable and your USB A/C devices. The driver-free installation with native driver support in Chrome, Mac, and Windows OS; The USB A/C Ethernet adapter dongle supports important performance features including Wake-on-Lan (WoL), Full-Duplex (FDX) and Half-Duplex (HDX) Ethernet, Crossover Detection, Backpressure Routing, Auto-Correction (Auto MDIX).
- INCREDIBLE PERFORMANCE - Supports full 10/100/1000Mbps gigabit ethernet performance over USB A/C's 5Gbps bus, faster and more reliable than most wireless connections. Link and Activity LEDs. USB powered, no external power required. Backward compatible with USB 2.0/1.1.✅ To reach 1Gbps, make sure to use CAT6 & up Ethernet cables.
- BROAD COMPATIBILITY - The USB A/C-Ethernet adapter is compatible with Windows 11/10/8.1/8/7/Vista/XP, Mac OSX 10.6/10.7/10.8/10.9/10.10/10.11/10.12, Linux kernel 3.x/2.6, Android and Chrome OS.Compatible with IEEE 802.3, IEEE 802.3u and IEEE 802.3ab. Supports IEEE 802.3az (Energy Efficient Ethernet).❌Do Not Support Windows RT. (NOT compatible with Nintendo Switch.)
- 18 MONTH WARRANTY - Exclusive BENFEI Unconditional 18-month Warranty ensures long-time satisfaction of your purchase; Friendly and easy-to-reach customer service to solve your problems timely.
Or skip the browser setup
If your real task is obtaining clean website screenshots rather than streaming a local desktop capture, ScreenshotNeo provides a single HTTP request. It accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; those steps can be disabled individually. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, with the result identified by X-Page-Verdict and X-Billed headers.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
See the ScreenshotNeo API documentation for the 63 capture options, including full-page lazy-image loading, CSS-selector elements, device presets, retina scale, PDF output, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, geolocation, caching, signed links, asynchronous webhooks, bulk capture and usage reporting. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. Every plan includes every feature: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots.
Create your free ScreenshotNeo account to try the 1,000 monthly screenshots without a card.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Frequently Asked Questions
Can I use PNG instead of JPEG?
Yes, when lossless text or transparency is essential, but PNG is often larger for photographic or complex screenshots. Keep the same length-prefix protocol and measure the complete pipeline.
Why not send each frame as a separate TCP packet?
TCP packet boundaries are not exposed as application message boundaries. A length prefix (or another explicit framing protocol) is required regardless of how the sender writes.
Should I open a new socket for every screenshot?
Usually no. Reusing one authenticated connection avoids connection setup overhead, but reconnect when errors or idle timeouts occur and cap queued work.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.

