#!/usr/bin/env dub
/+ dub.sdl:
name "vibe_tcp_echo"
dependency "vibe-core" version="2.14.0"
buildType "checked" {
buildOptions "optimize" "inline" "debugInfo"
}
platforms "linux"
+/
import (package) stdstd.(module) std.stdioCategory Symbols File handles _popen File isFileHandle openNetwork stderr stdin stdout Reading chunks lines readf readfln readln Writing toFile write writef writefln writeln Misc KeepTerminator LockType StdioException
Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio
is publically imported when importing std.stdio.
There are three layers of I/O:
The lowest layer is the operating system layer. The two main schemes are Windows and Posix.
C's stdio.h which unifies the two operating system schemes.
std.stdio, this module, unifies the various stdio.h implementations into
a high level package for D programs.
Source
std/stdio.d
stdio : (alias template) vibe_tcp_echo.writeln = std.stdio.writeln(T...)(T args)Equivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln;
import (package) vibevibe.(package) vibe.corecore.(module) vibe.core.netTCP/UDP connection and server handling.
net : (alias) vibe_tcp_echo.connectTCP = vibe.core.net.TCPConnection vibe.core.net.connectTCP(string host, ushort port, string bind_interface = null, ushort bind_port = cast(ushort)0u, core.time.Duration timeout = max()) @safeEstablishes a connection to the given host/port.
connectTCP, (alias) vibe_tcp_echo.listenTCP = vibe.core.net.TCPListener[] vibe.core.net.listenTCP(ushort port, void delegate(vibe.core.net.TCPConnection stream) nothrow @safe connection_callback, vibe.core.net.TCPListenOptions options = TCPListenOptions.reuseAddress) @safeStarts listening on the specified port.
'connection_callback' will be called for each client that connects to the
server socket. Each new connection gets its own fiber. The stream parameter
then allows to perform blocking I/O on the client socket.
The address parameter can be used to specify the network
interface on which the server socket is supposed to listen for connections.
By default, all IPv4 and IPv6 interfaces will be used.
listenTCP, (struct) vibe.core.net.TCPConnectionRepresents a single TCP connection.
TCPConnection, (struct) vibe.core.net.TCPListenerRepresents a listening TCP socket.
TCPListener;
import (package) vibevibe.(package) vibe.corecore.(module) vibe.core.streamGeneric stream interface used by several stream-like classes.
This module defines the basic (buffered) stream primitives. For concrete stream types, take a
look at the vibe.stream`` package. The vibe.stream.operations module contains additional
high-level operations on streams, such as reading streams by line or as a whole.
Note that starting with vibe-core 1.0.0, streams can be of either struct or class type.
Any APIs that take streams as a parameter should use a template type parameter that is tested
using the appropriate trait (e.g. isInputStream) instead of assuming the specific interface
type (e.g. InputStream).
stream : (enum) eventcore.driver.IOModeIOMode;
void void vibe_tcp_echo.echo(vibe.core.net.TCPConnection conn) @safeecho((struct) vibe.core.net.TCPConnectionRepresents a single TCP connection.
TCPConnection (parameter) vibe.core.net.TCPConnection connconn) @safe
{
scope (exit) (parameter) vibe.core.net.TCPConnection connconn.void vibe.core.net.TCPConnection.close() nothrow @safeclose();
ubyte[64] (local variable) ubyte[64] bufbuf;
(alias) object.size_t = ulongsize_t (local variable) ulong totaltotal;
while ((local variable) ulong totaltotal < 5)
{
const (local variable) const(ulong) lenlen = (parameter) vibe.core.net.TCPConnection connconn.ulong vibe.core.net.TCPConnection.read(scope ubyte[] dst, eventcore.driver.IOMode mode) @saferead((local variable) ubyte[64] bufbuf[0 .. 5 - (local variable) ulong totaltotal], (enum) eventcore.driver.IOModeIOMode.(enum value) eventcore.driver.IOMode.once = 1Process as much as possible with a single call
once);
assert((local variable) const(ulong) lenlen > 0);
(parameter) vibe.core.net.TCPConnection connconn.void vibe.core.net.TCPConnection.write(scope const(ubyte)[] bytes) @safewrite((local variable) ubyte[64] bufbuf[0 .. (local variable) const(ulong) lenlen]);
(local variable) ulong totaltotal += (local variable) const(ulong) lenlen;
}
}
void void D main()main()
{
auto (local variable) vibe.core.net.TCPListener listenerlistener = vibe.core.net.TCPListener vibe.core.net.listenTCP(ushort port, void delegate(vibe.core.net.TCPConnection stream) nothrow @safe connection_callback, string address, vibe.core.net.TCPListenOptions options = TCPListenOptions.reuseAddress) @safeStarts listening on the specified port.
'connection_callback' will be called for each client that connects to the
server socket. Each new connection gets its own fiber. The stream parameter
then allows to perform blocking I/O on the client socket.
The address parameter can be used to specify the network
interface on which the server socket is supposed to listen for connections.
By default, all IPv4 and IPv6 interfaces will be used.
listenTCP(0, ((struct) vibe.core.net.TCPConnectionRepresents a single TCP connection.
TCPConnection (parameter) vibe.core.net.TCPConnection connconn) nothrow @safe {
try void vibe_tcp_echo.echo(vibe.core.net.TCPConnection conn) @safeecho((parameter) vibe.core.net.TCPConnection connconn); catch ((class) object.ExceptionThe base class of all errors that are safe to catch and handle.
In principle, only thrown objects derived from this class are safe to catch
inside a catch block. Thrown objects not derived from Exception
represent runtime errors that should not be caught, as certain runtime
guarantees may not hold, making it unsafe to continue program execution.
Examples
bool gotCaught;
try
{
throw new Exception("msg");
}
catch (Exception e)
{
gotCaught = true;
assert(e.msg == "msg");
}
assert(gotCaught);
Exception (local variable) object.Exception errorerror) { assert(false, (local variable) object.Exception errorerror.(field) string object.Throwable.msgA message describing the error.
msg); }
}, "127.0.0.1");
scope (exit) (local variable) vibe.core.net.TCPListener listenerlistener.void vibe.core.net.TCPListener.stopListening() @safeStops listening and closes the socket.
stopListening();
const (local variable) const(ushort) portport = (local variable) vibe.core.net.TCPListener listenerlistener.vibe.core.net.NetworkAddress vibe.core.net.TCPListener.bindAddress() @property @safeThe local address at which TCP connections are accepted.
bindAddress.ushort vibe.core.net.NetworkAddress.port() const pure nothrow @property @safeThe port in host byte order.
port;
auto (local variable) vibe.core.net.TCPConnection clientclient = vibe.core.net.TCPConnection vibe.core.net.connectTCP(string host, ushort port, string bind_interface = null, ushort bind_port = cast(ushort)0u, core.time.Duration timeout = max()) @safeEstablishes a connection to the given host/port.
connectTCP("127.0.0.1", (local variable) const(ushort) portport);
scope (exit) (local variable) vibe.core.net.TCPConnection clientclient.void vibe.core.net.TCPConnection.close() nothrow @safeclose();
(local variable) vibe.core.net.TCPConnection clientclient.void vibe.core.net.TCPConnection.write(scope const(ubyte)[] bytes) @safewrite(cast(const(ubyte)[]) "hello");
ubyte[64] (local variable) ubyte[64] backback;
(alias) object.size_t = ulongsize_t (local variable) ulong lenlen;
while ((local variable) ulong lenlen < 5)
{
const (local variable) const(ulong) nn = (local variable) vibe.core.net.TCPConnection clientclient.ulong vibe.core.net.TCPConnection.read(scope ubyte[] dst, eventcore.driver.IOMode mode) @saferead((local variable) ubyte[64] backback[(local variable) ulong lenlen .. 5], (enum) eventcore.driver.IOModeIOMode.(enum value) eventcore.driver.IOMode.once = 1Process as much as possible with a single call
once);
assert((local variable) const(ulong) nn > 0);
(local variable) ulong lenlen += (local variable) const(ulong) nn;
}
assert(cast(const(char)[]) (local variable) ubyte[64] backback[0 .. (local variable) ulong lenlen] == "hello");
void std.stdio.writeln!(string, const(char)[])(string __param_0, const(char)[] __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("echoed: ", cast(const(char)[]) (local variable) ubyte[64] backback[0 .. (local variable) ulong lenlen]);
}