ipKangaroo (ipK) is a peer-to-peer Java communications suite developed at Rutgers University in 2000–2001. It combines a real-time VoIP voice client (ipKtalk), a multi-user text chat client/server (ipKchat), a stock quote ticker integrated into the chat window, and a shared splash-screen launcher (ipK). The project was originally hosted at ipkangaroo.no-ip.com and is released as open source under a beer-ware style license.
Version: 5.2.2
License: Open source — credit required if incorporated into other work
Runtime: Java 1.3 or greater
- Features
- Project Structure
- Application Overview
- Source Files — Launcher
- Source Files — VoIP (ipKtalk)
- Source Files — Text Chat (ipKchat)
- Source Files — Chat Server
- Source Files — CLI Client
- Source Files — Layer UI Framework
- Source Files — Support Classes
- Chat Protocol Commands
- Building
- Running
- System Requirements
- Authors & Credits
- License
| Capability | Detail |
|---|---|
| Voice over IP | Captures microphone audio via javax.sound.sampled; GZIP-compresses PCM data; transmits over TCP |
| Push-to-talk | Click the TALK button to record; click again to compress, packetize, and send |
| Compatibility Mode | Optional audio lock for systems where simultaneous capture/playback causes conflicts |
| Multi-user text chat | Server supports simultaneous users, private chat, two named chat rooms (J + K), name changes |
| Stock quotes | ipKchat includes a Quote Now! panel that scrapes live stock prices from Money.com |
| Audio alert | Plays alert.wav in ipKchat when a new connection arrives |
| Scrolling About dialog | AboutDialog uses a custom Swing layer framework for animated scrolling credits over a background image |
| Layer display framework | Reusable layer/ package: ImageLayer, TextLayer, Area coordinate mapping, zoom/pan, GIF export stub |
| Cross-platform launcher | ipK.java splash screen + ipK.c compiled native launcher; .bat scripts for Windows |
| Dual splash screens | Randomly selects redsplash.jpg or bluesplash.jpg on each launch |
ipKangaroo/
└── ipK_source/
├── ipK.java # Splash screen + launcher
├── ipK.c # Native C launcher (compiles to ipK.exe)
├── ipK.bat # Windows launch script for ipK splash
├── ipK.exe # Pre-compiled Windows native launcher
├── ipKtalk.java # VoIP client (main executable)
├── ipKtalk.bat # Windows launch script for ipKtalk
├── ipKchat.java # Text chat client (main executable)
├── ipKchat.bat # Windows launch script for ipKchat
├── Server.java # Multi-user chat server
├── Client.java # CLI text client
├── ClientFrom.java # CLI client receive thread
├── ClientTo.java # CLI client send thread
├── threadsAreDo.java # Per-connection chat worker thread
├── sThread.java # ipKtalk server connection listener
├── sKeepAlive.java # ipKchat server log relay thread
├── cThread.java # ipKtalk audio receive + playback thread
├── ipKFrom.java # ipKchat socket receive thread
├── About.java # ipKchat "About" dialog
├── AboutDialog.java # ipKtalk scrolling "About" dialog (uses layer/)
├── Info.java # Per-user connection record
├── infoQ.java # Stock quote data transfer object
├── Quote.java # Money.com stock quote scraper
├── Arguments.java # Command-line argument parser
├── LList.java # Linked list + stack implementation
├── DataDrawer.java # Interface: drawable component
├── DataOverlay.java # Interface: drawable overlay with dimensions
├── help.java # ipKtalk help window
├── helpC.java # ipKchat help window
├── mainClass # JAR manifest: Main-Class: ipKtalk
├── build.bat # Compile all Java sources
├── buildjar.bat # Compile + package ipK.jar
├── readme.txt # Original bundled README
├── alert.wav # Connection alert sound
├── redsplash.jpg # ipK splash screen (red variant)
├── bluesplash.jpg # ipK splash screen (blue variant)
├── ipk.jpg # ipKtalk banner image
├── ipkbk.jpg # AboutDialog background image
├── kangaroo.ico # Application icon
├── chat.gif # ipKchat toolbar icon
├── talk.gif # ipKtalk toolbar icon
└── layer/ # Reusable Swing layer display framework
├── Layer.java # Abstract base class for all layers
├── LayerDisplay.java # Swing component: renders layers with toolbar
├── LayerManager.java # Layer visibility/config dialog
├── ImageLayer.java # Layer: displays a scaled image
├── TextLayer.java # Layer: animated scrolling text
├── Area.java # Coordinate mapping (double ↔ pixels), zoom/pan
└── Utilities.java # Image loading, string sorting, quicksort
ipK.exe / ipK.bat
└── ipK.java (splash screen, 4-second timer)
└── launches: java ipKtalk
ipKtalk.bat
└── ipKtalk.java ← VoIP peer-to-peer audio client
├── sThread ← listens for incoming connection (server mode)
├── cThread ← receives + decompresses + plays audio
└── AboutDialog ← scrolling credits over ipkbk.jpg
ipKchat.bat
└── ipKchat.java ← Multi-user text chat GUI client
├── Server (subprocess) ← started via Runtime.exec("java Server")
├── sKeepAlive ← relays Server stdout to chat window
├── ipKFrom ← socket receive thread
├── Quote ← stock quote fetcher
└── About ← About dialog
ipK.java — Splash Screen
Entry point for the full suite. Extends java.awt.Frame.
- Randomly selects
redsplash.jpgorbluesplash.jpgand renders it at 400×200 pixels - Displays for 4 seconds via
Thread.sleep(4000) - Then executes
java ipKtalkviaRuntime.getRuntime().exec()and exits - Title bar:
"ipK - version: 5.2.2"
ipK.c — Native Windows Launcher
A small C program compiled to ipK.exe. Prints a startup banner to the console and calls execlp("java", " ipK", 0) to launch the Java splash screen. Provides a native double-click experience on Windows without requiring a .bat file.
execlp("java", " ipK", 0); /* run the command */ipK.bat — Windows Batch Launcher
Prints the ipKangaroo banner to the console and runs java ipK. Identical banner style used in ipKchat.bat and ipKtalk.bat.
ipKtalk.java — VoIP Client
The primary executable (Main-Class in the JAR). A full AWT-based peer-to-peer voice application using javax.sound.sampled.
Audio format: PCM Signed, 8 kHz, 8-bit, mono, signed big-endian.
Architecture:
ipKtalk (Frame + ActionListener)
├── Capture (inner Runnable) ← TargetDataLine mic recorder
├── FormatControls (inner) ← Returns AudioFormat definition
├── sThread ← Server mode: waits for incoming TCP connection
└── cThread ← Receives, decompresses, queues, and plays audio
├── Monitor (inner Thread) ← Polls audio queue; triggers Playback
└── Playback (inner Runnable) ← SourceDataLine playback
Key methods:
| Method | Description |
|---|---|
ConnecT() |
Client mode: opens Socket to host:port; starts cThread. Server mode: opens ServerSocket; starts sThread to wait |
DisconnecT() |
Sends a 0 length signal + null audio object; closes sockets; resets UI state |
startMic() |
Sets status, starts Capture thread, enforces 1-second minimum recording |
stopMic() |
Stops capture; GZIP-compresses the PCM byte array; writes length + compressed bytes via ObjectOutputStream; re-enables Talk button |
reset() |
Disconnects and relaunches ipKtalk as a fresh child process (auto-reconnect) |
Reset_Action() |
Sends -1 length signal to remote end to trigger their reset, then resets locally |
Compatibility Mode (-m flag / menu checkbox): Wraps AudioSystem.getLine() calls in a busy-wait lock integer to prevent simultaneous open/close of the audio line on hardware that does not support it. Used on older Windows or Linux systems.
CLI flags:
| Flag | Description |
|---|---|
-c <host> |
Connect to host immediately on launch |
-s |
Start in server (listen) mode immediately |
-p <port> |
Override default port (69) |
-m |
Enable Compatibility Mode |
-t <host> |
Pre-fill host field, don't connect |
-f |
Pre-select Server checkbox, don't connect |
cThread.java — Audio Receive & Playback Thread
Receives GZIP-compressed audio packets from the remote peer and plays them through the system audio output.
Threading model:
cThread.run()
→ reads: int length via BufferedReader (signals end-of-clip at -1, disconnect at 0)
→ reads: byte[] compressed audio via ObjectInputStream
→ GZIP-decompresses to raw PCM bytes
→ adds to vec (Vector) buffer; increments waiting counter
Monitor.run() (inner Thread, polls every 200ms)
→ when waiting > 0 and playing == 0:
→ dequeues from vec
→ wraps bytes in AudioInputStream
→ starts Playback thread
Playback.run() (inner Runnable)
→ opens SourceDataLine
→ streams PCM bytes via line.write()
→ drains and closes line
Audio buffer size: 16,384 bytes (bufSize = 16384)
In Compatibility Mode, cThread and ipKtalk.Capture share a lock integer to serialize access to AudioSystem.getLine(), preventing conflicts on hardware that cannot support simultaneous capture and playback.
sThread.java — VoIP Connection Listener Thread
A short-lived Thread that blocks on ipKtalk.ss.accept() (the pre-opened ServerSocket) waiting for an incoming VoIP connection. On accept:
- Sets up
ipKtalk.os,ipKtalk.o(theObjectOutputStream) for sending - Sets
ipKtalk.CurCon = 1 - Updates the status text field with the remote address
- Starts
cThreadto listen for incoming audio - Enables the Start and Disconnect buttons
- Terminates (this thread is single-use per connection)
AboutDialog.java — Scrolling Credits Dialog
A Swing JDialog that displays an animated scrolling credits screen using the layer/ framework.
Layers used:
ImageLayer— rendersipkbk.jpgas a full-window backgroundTextLayer— scrolls the credits upward atINIT_SPEED = 2pixels perDELAY = 100mstick
Credits displayed:
- ipKangaroo, Rutgers University
- ipKtalk: Daneyand Singley, Vivek Bedi
- ipkangaroo.no-ip.net: Evan Lerer, Mary Alexander, Chi-Wei Yung, Michael Weakland
- Special thanks: Roland Wunderlich (scroll capabilities + development support)
- Special thanks: Roderick Rivera (development support)
- Audio assistance: Sun Microsystems © 1999
- Java Scroll capabilities: © 1998 Roland Wunderlich
Click once to pause/resume scrolling; double-click to reverse direction.
help.java — ipKtalk Help Window
A standalone AWT Frame that displays help text for ipKtalk. Launched from the File → Help menu item.
ipKchat.java — Text Chat GUI Client
Full-featured AWT multi-user chat client. Can operate as a client connecting to a Server instance, or start its own Server subprocess.
Key GUI elements:
ta1— main scrolling conversationTextAreatf4— message inputTextField(sends on Enter key)tf1,tf3— host and ID fieldsConnect/Disconnect/Start Server/Stop Serverbuttons- Optional
Quote Now!panel (panelbot) for stock lookups
Key methods:
| Method | Description |
|---|---|
Start_SAction() |
Launches java Server as a child process; starts sKeepAlive to relay its stdout to ta1 |
Stop_SAction() |
Destroys the Server child process; resets UI |
QN_Action() |
Toggles the Quote Now! stock ticker panel on/off |
keyTyped() |
Sends text from tf4 on Enter; handles %q disconnect command |
Quit_Action() |
Sends %q\n to server, closes socket, exits |
LipKtalk_Action() |
Launches ipKtalk.bat as a subprocess |
Stock quote integration: When Quote Now! is active, the getQ button calls Quote.getQ(symbol) and appends name, price, change, and volume to ta1.
ipKFrom.java — ipKchat Socket Receive Thread
Reads lines from the ipKchat socket and dispatches them:
ALERT+cboxM(alert sound enabled): playsalert.wavviaApplet.newAudioClip()QUIT: closes socket and resets connect/disconnect button state- All other lines: appended to
ipKchat.ta1
sKeepAlive.java — Server Log Relay Thread
Runs while ipKchat.serverr == 1. Reads stdout from the Server child process line by line and appends each line to ipKchat.ta1 — providing a live server log view inside the chat window.
About.java — ipKchat About Dialog
An AWT Frame displaying the ipKchat credits in a TextArea:
ipKchat v5.2.2
Developed by:
Daneyand Singley, Vivek Bedi
(c) 2001 ipKangaroo, All Rights Reserved.
helpC.java — ipKchat Help Window
Standalone AWT Frame displaying help text for ipKchat. Launched from the File → Help menu item.
Server.java — Multi-User Chat Server
Standalone server. Accepts connections on port 2222 (configurable via -p), reads a username from each new connection, and hands it off to a threadsAreDo worker thread.
main():
ServerSocket.accept() loop
→ read username from first line
→ new threadsAreDo(socket, username).start()
threadsAreDo.java — Per-Connection Chat Worker Thread
One thread per connected client. Manages a shared Hashtable<String, Info> for all connected users. Parses the ipKchat text protocol and routes messages.
User registry: static Map users = new Hashtable() — shared across all threadsAreDo instances.
Protocol commands:
| Command | Description |
|---|---|
%c <user> |
Connect to another user for private one-on-one chat |
%t |
Terminate current private connection or leave chat room |
%u |
List all connected users with talk status and login time |
%i <newname> |
Change your display name (only when not in a chat) |
%s |
Toggle "Unavailable" status — blocks incoming connection requests |
%j |
Join J-ChatRoom (group chat channel 1) |
%k |
Join K-ChatRoom (group chat channel 2) |
%q |
Disconnect and quit |
%%text |
Send a literal message starting with % |
| any text | Routes to current connected user or active chat room |
Duplicate name handling: If a client tries to connect with an already-registered username, the server sends an error message and immediately closes that connection without affecting the existing user.
Client.java — Command-Line Chat Client
Standalone CLI client. Connects to Server and spawns two threads: ClientFrom (receives) and ClientTo (sends). Supports -h <host> and -p <port> flags.
ClientFrom.java — CLI Receive Thread
Reads from the server socket line by line and prints to stdout. Exits on socket close.
ClientTo.java — CLI Send Thread
Sends the username as the first line (server login), then reads stdin line by line and writes to the server socket. Type %q to disconnect and exit.
The layer/ package is a reusable Swing-based layered display framework used by AboutDialog to render the animated scrolling credits screen. It was designed as a general-purpose data visualization component.
Layer.java — Abstract Layer Base Class
All displayable layers extend this class.
| Method | Description |
|---|---|
draw(Graphics g, Area a) |
Abstract: render this layer onto g within coordinate space a |
handleClick(MouseEvent e, Area a) |
Abstract: handle a mouse click; return true if handled |
configure() |
Optional: shows a configuration dialog (default shows "no options" message) |
getName() / toString() |
Returns layer name; appends " (hidden)" if not visible |
isVisible() |
Returns visibility state |
LayerDisplay.java — Layered Canvas Swing Component
Extends JComponent. Renders an ordered stack of Layer objects onto a LayerCanvas, with an optional toolbar for interaction tools.
Toolbar buttons:
| Button | Tool | Cursor |
|---|---|---|
| Select | SELECT |
Hand cursor — delegates clicks to layers |
| Zoom | ZOOM |
Default cursor — rubber-band zoom rectangle |
| Center | CENTER |
Crosshair — re-centers the Area on click |
| Zoom to Fit | — | Resets Area to full bounds; repacks window |
| Refresh | — | Repaints the canvas |
| Layers… | — | Opens LayerManager dialog |
| Save GIF | — | (stub — Utilities.saveGIF not implemented) |
Inner class LayerCanvas: The actual JComponent that calls layer.draw(g, area) for each visible layer. Handles mouse events for all three cursor modes. Zoom rubber-band uses XOR drawing mode for the selection rectangle.
LayerManager.java — Layer Visibility Dialog
A non-modal JDialog listing all layers in a JList. Double-click or the Show/Hide button toggles layer visibility. Right-click shows a popup menu with Show/Hide and Configure options.
ImageLayer.java — Background Image Layer
Renders a single image scaled to fill the entire LayerDisplay canvas. Caches the scaled instance until the canvas is resized.
public ImageLayer(String name, Image image)Used in AboutDialog to display ipkbk.jpg as the background for the scrolling credits.
TextLayer.java — Animated Scrolling Text Layer
Renders an array of String[] lines scrolling upward at a configurable speed using a Swing Timer.
| Constant | Value | Description |
|---|---|---|
INDENT |
16 px | Left margin for all text lines |
DELAY |
100 ms | Timer tick interval |
INIT_SPEED |
2 px | Initial scroll speed (pixels per tick) |
FONT |
Sans-Serif Bold 13pt | Text font |
COLOR |
Color.black |
Text color |
Interaction:
- Single click: pause / resume scrolling
- Double-click: reverse scroll direction
- Scrolling wraps: when all text scrolls off the top, resets from the bottom
Used in AboutDialog to scroll the project credits over the background image.
Area.java — Coordinate Space Mapper
Maps a double-precision coordinate domain (x, y, width, height) to pixel screen coordinates. Supports zoom, pan, and aspect-ratio preservation.
Key methods:
| Method | Description |
|---|---|
translate(double x, double y) |
Maps a double coordinate pair to a screen Point |
translate(double value, boolean horizontal) |
Maps a scalar width or height to pixels |
withinRange(Point p, double range, double x, double y) |
Tests if a screen click is within range of a double-domain point — for hit detection in layers |
zoom(Point center, double zoomFactor) |
Zooms in/out around a screen pixel point |
zoom(Point start, Point end, boolean zoomIn) |
Zooms to a rubber-band rectangle |
center(Point) |
Re-centers the view on a screen pixel |
reset() |
Restores the original full-bounds view |
Maximum zoom factor: 1000× (MAX_ZOOM = 1000.0).
Aspect ratio is enforced on every setScreen() call (called before each paint).
Utilities.java — Layer Utility Methods
| Method | Description |
|---|---|
getImage(String path) |
Loads an Image from the classpath via ClassLoader.getSystemResource() |
getImageIcon(String path) |
Returns an ImageIcon (currently returns an empty icon — stub) |
getLongestString(Object[] a) |
Returns the longest toString() from an array — used to size JList prototype cell |
sort(Comparable[] a) |
In-place quicksort for Comparable arrays |
Quote.java — Stock Quote Scraper
Fetches a live stock quote from http://quote.money.com/money/quote/qc?symbols=<symbol> by opening a URL connection and scraping <b> tags from the HTML response.
Returns an infoQ object with fields: symbol, name, price, change, volume.
Note: The money.com URL and HTML structure used here are from 2001 and no longer active.
infoQ.java — Stock Quote Data Object
Implements Serializable. Simple data holder:
| Field | Type |
|---|---|
symbol |
String |
name |
String |
price |
String |
change |
String |
volume |
String |
Info.java — Chat User Record
Stores all per-connection state for threadsAreDo:
| Field | Description |
|---|---|
name |
Display username |
s |
The user's Socket |
connStamp |
System.currentTimeMillis() at connection time |
connected |
Reference to the Info of the user currently in private chat with this user |
talkStamp |
Timestamp when the current private chat began |
room |
Chat room membership: 0 = none, 1 = J-ChatRoom, 2 = K-ChatRoom |
toString() formats user details for the %u command output.
Arguments.java — Command-Line Argument Parser
Originally written by Roland Wunderlich, used with permission. Parses -flag value style CLI arguments into a Map<String, String> (flag → value) and a List<String> of positional (unmodified) arguments.
| Method | Description |
|---|---|
isSpecified(String modifier) |
Returns true if -modifier was present |
getModified(String modifier) |
Returns the value following -modifier |
getModifiedInt(String modifier) |
Parses the value as an int |
getUnmodified() |
Returns positional (non-flag) arguments |
LList.java — Linked List & Stack
Located in package collections.impl. A singly-linked list implementation written by Terence Parr (MageLang Institute). Implements both the List and Stack interfaces.
| Method | Description |
|---|---|
add(Object) / append(Object) |
Appends to tail |
includes(Object) |
Linear search for membership |
elementAt(int) |
O(n) index access |
length() |
Returns element count |
elements() |
Returns Enumeration via LLEnumeration |
push(Object) |
Inserts at head (stack push) |
pop() |
Removes and returns head (stack pop) |
height() |
Returns element count (stack interface) |
DataDrawer.java — Drawable Component Interface
public interface DataDrawer {
void setDisplay(DataDisplay parent);
void draw(Graphics g, Dimension d);
boolean handleClick(Point p, Dimension d);
}Interface for components that can draw themselves and respond to clicks within a DataDisplay. Predates the layer/ framework.
DataOverlay.java — Sized Drawable Overlay Interface
Extends DataDrawer. Adds getSize() and getPreferredSize() for overlays that report their own preferred dimensions.
Full command reference for connected ipKchat / Client users:
%c <user> — Start a private conversation with <user>
%t — Stop the current private talk or leave a chat room
%u — List all connected users with status and timestamps
%i <newname> — Change your username (must not be in a conversation)
%s — Toggle "Unavailable" status (blocks incoming connection requests)
%j — Join J-ChatRoom (group chat)
%k — Join K-ChatRoom (group chat)
%q — Disconnect and quit
%%<text> — Send a message starting with % (strips the leading %)
build.batWhich runs:
javac ipKtalk.java
javac ipKchat.java
javac Client.java
javac Server.java
javac ipK.javabuildjar.batWhich runs:
gcc ipK.c
javac ipKtalk.java ipKchat.java Client.java Server.java ipK.java
jar cmf mainClass ipK.jar *.class *.gif *.jpg layerThe resulting ipK.jar has Main-Class: ipKtalk and includes all classes, images, GIFs, and the layer/ package.
ipK.bat
REM or double-click: ipK.exeipKtalk.bat
REM or: java ipKtalkipKchat.bat
REM or: java ipKchatjava ipKtalk [-c <host>] [-s] [-p <port>] [-m] [-t <host>] [-f]
java Server [-p <port>]
java Client [-h <host>] [-p <port>] [username]
| Component | Requirement |
|---|---|
| Java runtime | JDK / JRE 1.3 or greater (required) |
| CPU | 200 MHz or faster strongly recommended |
| Audio hardware | Sound card with microphone and speakers (required for ipKtalk) |
| Network | Internet connection required for ipKtalk and ipKchat |
| OS | Windows 2000+, Linux 2.4+ recommended; Windows 95 may not work |
Note: Windows 95 users may experience instability. If the program crashes and the user cannot close it, close the console window that launched the program.
| Name | Role |
|---|---|
| Daneyand "DJ" Singley | Project lead; ipKtalk, ipKchat, core networking, chat server |
| Vivek Bedi | Co-developer; ipKtalk, ipKchat |
| Evan Lerer | ipkangaroo.no-ip.net website development |
| Mary (Marie) Alexander | ipkangaroo.no-ip.net website development |
| Chi-Wei (ChiWei) Yung | ipkangaroo.no-ip.net website development |
| Michael Weakland | ipkangaroo.no-ip.net website development |
| Roland Wunderlich | Arguments.java (command-line parser, © 1998); development support; Java Scroll capabilities (© 1998) |
| Roderick Rivera | Development support |
| Terence Parr (MageLang Institute) | LList.java — linked list / stack implementation |
| Sun Microsystems | Audio capture/playback code patterns from CapturePlayback.java (© 1999) |
Institutional affiliation: Rutgers University, 2000–2001
ipKangaroo is open source. Released by Daneyand Singley for the internet community.
"If you enjoy this code or incorporate any part of it into your application, please provide credit. Beer-ware as it were." — Daneyand "DJ" Singley, daneyand@yahoo.com
© 2000–2001 ipKangaroo. All rights reserved.
Java Scroll capabilities © 1998 Roland Wunderlich. All rights reserved.
Audio assistance © 1999 Sun Microsystems, Inc. All rights reserved.