The root cause of both bugs was that each peer had a single peerConnection field used for both sending and receiving streams: 1. Starting a share while receiving another's stream failed because sendOfferTo() saw the existing incoming PC and bailed out, so the outgoing stream was never sent. 2. Stopping a share killed the other person's stream because stopSharing() closed ALL peer connections, including the incoming one used to receive their stream. Fix by splitting into outgoingPC (created via sendOfferTo, used for sending our stream) and incomingPC (created via handleOffer, used for receiving their stream). ICE candidates now embed a direction flag so the remote side routes them to the correct PC. https://claude.ai/code/session_01ALSwS4S8EHiP81i2KMsb9Y |
||
|---|---|---|
| .. | ||
| src | ||
| static | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| lanshare.crt | ||
| lanshare.key | ||
| README.md | ||
LAN Share
A peer-to-peer screen sharing application for local networks. No accounts, no cloud services — just open a browser and share.
Features
- WebRTC P2P: Direct peer-to-peer connections, video never touches the server
- Audio support: Optionally share system audio with your screen
- Multiple streams: View multiple shared screens, select which one to focus on
- Zero config: Just run the server and open the URL in any browser
- Keyboard shortcuts:
Ffor fullscreen,Mfor mute,Escapeto expand sidebar
Building
cargo build --release
The binary will be at target/release/lanshare.
Running
./target/release/lanshare
Or with cargo:
cargo run --release
The server starts on http://0.0.0.0:8080 by default.
CLI Options
Usage: lanshare [OPTIONS]
Options:
-H, --host <IP> IP address to bind to [default: 0.0.0.0]
-p, --port <PORT> Port to listen on [default: 8080]
-v, --verbose Enable verbose/debug logging
-q, --quiet Quiet mode - only show errors
-h, --help Print help
-V, --version Print version
Examples:
# Listen on a specific interface
lanshare --host 192.168.1.100 --port 3000
# Localhost only (for testing)
lanshare -H 127.0.0.1
# Quiet mode
lanshare -q
CLI Options
LAN Share - Peer-to-peer screen sharing for local networks
Usage: lanshare [OPTIONS]
Options:
-H, --host <HOST> Host address to bind to [default: 0.0.0.0]
-p, --port <PORT> Port to listen on [default: 8080]
-v, --verbose Enable verbose logging
-h, --help Print help
-V, --version Print version
Examples
# Run on default settings (0.0.0.0:8080)
lanshare
# Run on a specific port
lanshare -p 3000
# Bind to localhost only
lanshare -H 127.0.0.1 -p 8080
# Run with verbose logging
lanshare -v
Usage
- Start the server on any machine in your LAN
- Open
http://<server-ip>:8080in a browser on each device - Enter your name when prompted
- Click "Start Sharing" to share your screen
- Select shared screens from the sidebar to view them
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Signaling Server │
│ (Rust/Axum/WebSocket) │
│ - Peer discovery │
│ - Relays SDP offers/answers (with bundled candidates) │
└─────────────────────────────────────────────────────────────┘
│ │
│ WebSocket │ WebSocket
│ (signaling only) │ (signaling only)
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Peer A │◄────────────────────►│ Peer B │
│ (Browser) │ Direct WebRTC │ (Browser) │
└─────────────┘ (video/audio) └─────────────┘
100% Local Network — No external services, simple direct connections:
- No STUN/TURN servers needed
- No trickle ICE — candidates bundled directly in SDP
- One offer + one answer = connected
- Video/audio streams stay entirely on your LAN
Browser Support
Tested on:
- Chrome/Chromium
- Firefox
- Edge
- Safari (macOS)
Note: Screen sharing with audio requires Chrome/Edge on Windows/macOS. Firefox and Linux may have limited audio capture support depending on the system.
Configuration
Command-line options take precedence over defaults. See lanshare --help for all options.
Environment variables:
RUST_LOG: Override log level (e.g.,RUST_LOG=lanshare=debug)
Security Notes
- This is designed for trusted local networks only
- No authentication — anyone with the URL can join
- No encryption beyond what WebRTC provides by default (DTLS-SRTP)
- Don't expose to the internet without additional security measures
License
MIT