Network Your Software
Ice
A Comprehensive RPC Framework
Flexible
Make synchronous and asynchronous invocations using TCP, UDP, SSL/TLS, WebSockets, and Bluetooth. Bidirectional connections allow a server to reuse a connection established by a client to make callbacks.
Secure
Ice offers powerful and easy to use security features. The IceSSL plug-in uses your operating system's SSL/TLS stack to encrypt your data and authenticate your connections.
Fast
Ice uses a compact, efficient binary protocol to minimize CPU and bandwidth consumption.

Everywhere
Develop in C++, C#, Java, JavaScript, MATLAB, Objective-C, PHP, Python, and Ruby. Deploy on Linux, macOS, Windows, Android, and iOS.
An Introduction to
Ice
Step 1: Write Slice
Define the interfaces and operations for your application in Slice, then compile them to any supported language.
Step 2: Write Server
Implement the server's interfaces and operations in C++, C#, Java, Objective-C, or Python.
Step 3: Write Client
Connect to your server using a client written in any language, from any platform.
Ice's Interface Definition Language
// Printer.ice
module Demo
{
interface Printer
{
// A client can invoke this operation on a server.
// In this example we print the string s
void printString(string s);
}
}
Compile Slice to C++, C#, Java, ...
$ slice2cpp Printer.ice # Printer.h, Printer.cpp
$ slice2cs Printer.ice # Printer.cs
$ slice2java Printer.ice # Demo/Printer.java, ...
$ slice2js Printer.ice # Printer.js
$ slice2matlab Printer.ice # +Demo/PrinterPrx.m
$ slice2objc Printer.ice # Printer.h, Printer.m
$ slice2php Printer.ice # Printer.php
$ slice2py Printer.ice # Printer.py
$ slice2rb Printer.ice # Printer.rb
$ slice2swift Printer.ice # Printer.swift
//// Implement Printer interface//
class PrinterI : public Demo::Printer
{
public:
virtual void printString(string s, const Ice::Current&) override
{
cout << s << endl;
}
};
// Initialize Ice communicator - used for interacting with the Ice runtime
Ice::CommunicatorHolder ich(argc, argv);
// Instantiate a new PrinterI servant - the implementation of your Printer
auto servant = make_shared<PrinterI>();
// Create object adapter - a container for your servants. Listens on port 10000
auto adapter = ich->createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000");
// Add the servant object to the object adapter with identity "SimplePrinter"
adapter->add(servant, ich->stringToIdentity("SimplePrinter"));
// Activate object adapter - accept incoming requests and dispatch them to servants
adapter->activate();
// Wait for communicator to shut down
ich->waitForShutdown();
//// Implement Printer interface//
public class PrinterI : Demo.PrinterDisp_
{
public override void printString(string s, Ice.Current current)
{
Console.WriteLine(s);
}
}
// Initialize Ice communicator - used for interacting with the Ice runtime
using(var communicator = Ice.Util.initialize(ref args))
{
// Instantiate a new PrinterI servant - the implementation of your Printer
var servant = new PrinterI();
// Create object adapter - a container for your servants. Listens on port 10000
var adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000");
// Add the servant object to the object adapter with identity "SimplePrinter"
adapter.add(servant, communicator.stringToIdentity("SimplePrinter"));
// Activate object adapter - accept incoming requests and dispatch them to servants
adapter.activate();
// Wait for communicator to shut down
communicator.waitForShutdown();
}
//// Implement Printer interface//
public class PrinterI implements Demo.Printer
{
@Override
public void printString(String s, com.zeroc.Ice.Current current)
{
System.out.println(s);
}
}
// Initialize Ice communicator - used for interacting with the Ice runtime
try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args))
{
// Instantiate a new PrinterI servant - the implementation of your Printer
com.zeroc.Ice.Object servant = new PrinterI();
// Create object adapter - a container for your servants. Listens on port 10000
com.zeroc.Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000");
// Add the servant object to the object adapter with identity "SimplePrinter"
adapter.add(servant, communicator.stringToIdentity("SimplePrinter"));
// Activate object adapter - accept incoming requests and dispatch them to servants
adapter.activate();
// Wait for communicator to shut down
communicator.waitForShutdown();
}
//// Implement Printer interface//
@interface PrinterI : DemoPrinter<DemoPrinter>
@end
@implementation PrinterI
-(void) printString:(NSMutableString*)s current:(ICECurrent*)current
{
printf("%s\n", [s UTF8String]);
}
@end
// Initialize Ice communicator - used for interacting with the Ice runtime
id<ICECommunicator> communicator = communicator = [ICEUtil createCommunicator:&argc argv:argv];
// Instantiate a new PrinterI servant - the implementation of your Printer
ICEObject *servant = [PrinterI printer];
// Create object adapter - a container for your servants. Listens on port 10000
id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints: @"SimplePrinterAdapter"
endpoints: @"tcp -p 10000"];
// Add the servant object to the object adapter with identity "SimplePrinter"
[adapter add:servant identity:[communicator stringToIdentity:@"SimplePrinter"]];
// Activate object adapter - accept incoming requests and dispatch them to servants
[adapter activate];
// Wait for communicator to shut down
[communicator waitForShutdown];
// Destroy Ice communicator
[communicator destroy];
## Implement Printer interface#
class PrinterI(Demo.Printer):
def printString(self, s):
print(s)
# Initialize Ice communicator - used for interacting with the Ice runtime
with Ice.initialize(sys.argv) as communicator:
# Instantiate a new PrinterI servant - the implementation of your Printer
servant = PrinterI()
# Create object adapter - a container for your servants. Listens on port 10000
adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000")
# Add the servant object to the object adapter with identity "SimplePrinter"
adapter.add(servant, communicator.stringToIdentity("SimplePrinter"))
# Activate object adapter - accept incoming requests and dispatch them to servants
adapter.activate()
# Wait for communicator to shut down
communicator.waitForShutdown()
//// Implement Printer interface//
class PrinterI: Printer {
func printString(s: String) {
print(s)
}
}
// Initialize Ice communicator - used for interacting with the Ice runtime
let communicator = try Ice.initialize(CommandLine.arguments)
defer { communicator.destroy() }
// Instantiate a new PrinterI servant - the implementation of your Printer
let servant = PrinterI()
// Create object adapter - a container for your servants. Listens on port 10000
let adapter = try communicator.createObjectAdapterWithEndpoints(name: "SimplePrinterAdapter", endpoints: "tcp -p 10000")
// Add the servant object to the object adapter with identity "SimplePrinter"
try adapter.add(servant: PrinterDisp(servant), id: Ice.stringToIdentity("SimplePrinter"))
// Activate object adapter - accept incoming requests and dispatch them to servants
try adapter.activate()
// Wait for communicator to shut down
communicator.waitForShutdown()
// Initialize Ice communicator - used for interacting with the Ice runtime
Ice::CommunicatorHolder ich(argc, argv);
// Create a proxy to the remote Printer object
auto obj = ich->stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");
// Downcast obj to Printer proxy
auto printer = Ice::checkedCast<PrinterPrx>(obj);
// Invoke "printString" operation on remote Printer object
printer->printString("Hello World!");
// Initialize Ice communicator - used for interacting with the Ice runtime
using(var communicator = Ice.Util.initialize(ref args))
{
// Create a proxy to the remote Printer object
var obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");
// Downcast obj to Printer proxy
var printer = Demo.PrinterPrxHelper.checkedCast(obj);
// Invoke "printString" operation on remote Printer object
printer.printString("Hello World!");
}
// Initialize Ice communicator - used for interacting with the Ice runtime
try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args))
{
// Create a proxy to the remote Printer object
com.zeroc.Ice.ObjectPrx obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");
// Downcast obj to Printer proxy
Demo.PrinterPrx printer = Demo.PrinterPrx.checkedCast(obj);
// Invoke "printString" operation on remote Printer object
printer.printString("Hello World!");
}
// Initialize Ice communicator - used for interacting with the Ice runtime
id<ICECommunicator> communicator = [ICEUtil createCommunicator:&argc argv:argv];
// Create a proxy to the remote Printer object
id<ICEObjectPrx> obj = [communicator stringToProxy:@"SimplePrinter:tcp -h serverhost.serverdomain -p 10000"];
// Downcast obj to Printer proxy
id<DemoPrinterPrx> printer = [DemoPrinterPrx checkedCast:obj];
// Invoke "printString" operation on remote Printer object
[printer printString:@"Hello World!"];
// Destroy Ice communicator
[communicator destroy];
# Initialize Ice communicator - used for interacting with the Ice runtime
with Ice.initialize(sys.argv) as communicator:
# Create a proxy to the remote Printer object
obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000")
# Downcast obj to Printer proxy
printer = Demo.PrinterPrx.checkedCast(obj)
# Invoke "printString" operation on remote Printer object
printer.printString("Hello World!")
// Initialize Ice communicator - used for interacting with the Ice runtime
const communicator = Ice.initialize();
// Create a proxy to the remote Printer object
const obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");
// Downcast obj to Printer proxy
const printer = await Demo.PrinterPrx.checkedCast(obj);
// Invoke "printString" operation on remote Printer object
await printer.printString("Hello World!");
// Destroy Ice communicator
communicator.destroy();
% Initialize Ice communicator - used for interacting with the Ice runtime
communicator = Ice.initialize();
% Create a proxy to the remote Printer object
obj = communicator.stringToProxy('SimplePrinter:tcp -h serverhost.serverdomain -p 10000');
% Downcast obj to Printer proxy
printer = Demo.PrinterPrx.checkedCast(obj);
% Invoke "printString" operation on remote Printer object
printer.printString('Hello World!');
% Destroy Ice communicator
communicator.destroy();
// Initialize Ice communicator - used for interacting with the Ice runtime
$communicator = Ice\initialize();
// Create a proxy to the remote Printer object
$obj = $communicator->stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");
// Downcast obj to Printer proxy
$printer = Demo\PrinterPrxHelper::checkedCast($obj);
// Invoke "printString" operation on remote Printer object
$printer->printString("Hello World!");
// Destroy Ice communicator
$communicator->destroy();
# Initialize Ice communicator - used for interacting with the Ice runtime
communicator = Ice::initialize(ARGV)
# Create a proxy to the remote Printer object
obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000")
# Downcast obj to Printer proxy
printer = Demo::PrinterPrx::checkedCast(obj)
# Invoke "printString" operation on remote Printer object
printer.printString("Hello World!")
# Destroy Ice communicator
communicator.destroy();
// Initialize Ice communicator - used for interacting with the Ice runtime
let communicator = try Ice.initialize(CommandLine.arguments)
defer { communicator.destroy() }
// Create a proxy to the remote Printer object
let obj = try communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000")!
// Downcast obj to Printer proxy
let printer = try checkedCast(prx: obj, type: PrinterPrx.self)!
// Invoke "printString" operation on remote Printer object
try printer.printString("Hello World!")
Asynchronous Programming using Futures and Async/Await
Write concise and clean applications with standard language classes and constructs.
// Person.ice
module Demo
{
interface Person
{
int computeCreditScore();
}
}
// Obtain person proxy
auto person = ...
// Invoke "computeCreditScore" asynchronously on remote Person object
std::future<int> future = person->computeCreditScoreAsync();
//// Do other work//
// Retrieve result from future
auto creditScore = future.get();
// Obtain person proxy
var person = ...
// Invoke "computeCreditScore" asynchronously on remote Person object
// and await the result (must be called from an async function)
var creditScore = await person.computeCreditScoreAsync();
// Obtain person proxy
Demo.PersonPrx person = ...
// Invoke "computeCreditScore" asynchronously on remote Person object
CompletableFuture<Integer> future = person.computeCreditScoreAsync();
//// Do other work//
// Retrieve result from future
Integer creditScore = future.get();
# Obtain person proxy
person = ...
# Invoke "computeCreditScore" asynchronously on remote Person object
creditScore = await Ice.wrap_future(person.computeCreditScoreAsync())
// Obtain person proxy
const person = ...
// Invoke "computeCreditScore" asynchronously on remote Person object
// and await the result (must be called from an async function)
const creditScore = await person.computeCreditScore();
% Obtain person proxy
person = ...
% Invoke "computeCreditScore" asynchronously on remote Person object
future = person.computeCreditScoreAsync()
%% Do other work%
% Retrieve result from future
creditScore = future.fetchOutputs()
// Obtain person proxy
let person = ...
// Invoke "computeCreditScore" asynchronously on remote Person object
// Ice for Swift uses PromiseKit for its async API
firstly {
person.computeCreditScoreAsync()
}.then { creditScore in
// Use result
}
Language Mappings
Ice Services
Ice is more than a RPC framework. It also provides a number of complementary services for your networked applications.
Get Started with Ice
Whether you're working on an enterprise application or hobbyist project, Ice makes it easy to network your software.
Download Ice Documentation