How to cleanup after Socket.bind on Linux?
Ali Çehreli
acehreli at yahoo.com
Mon Aug 26 20:30:10 PDT 2013
The following simple socket example is trying to cleanup after itself,
except the bind() call. As I repeat in the QUESTION comment below, I
have read the man page of bind and I know that I need to unlink a path.
How can I get that path?
The program waits on localhost:8080, receives N number of data and
responds with "Hello World!".
The problem is, currently the program apparently leakes some resources.
It cannot be started a second time for 8080 still being in use, unless
you wait for several seconds, presumably until the OS does the cleanup.
import std.stdio;
import std.socket;
import std.string;
enum port = 8080;
void main()
{
server();
}
void server()
{
// Prepare the socket
auto listener = new TcpSocket();
scope (exit) {
writefln("Shutting down and closing the listener");
listener.shutdown(SocketShutdown.BOTH);
listener.close();
}
/*
* The port to listen to
*
* Note that the following perhaps naive code does not work on OSX. Try
* the following line instead:
*
* listener.bind(new InternetAddress(port));
*/
Address[] addresses = getAddress("localhost", port);
writefln("Addresses: %s", addresses);
auto address = addresses[0];
writefln("Address: %s", address);
listener.bind(address);
scope (exit) {
/*
* QUESTION: What to do here?
*
* According to 'man bind', the path that represents the
address must
* be unlink'ed. However, the path seems to be available only
through
* UnixAddress.path but UnixAddress is not available by default
and it
* is not convenient to use (e.g. it does not have a
constructor that
* takes the port value).
*/
}
// Wait for the client
listener.listen(1);
writeln("Waiting for the client");
// Accept the connection
Socket connection = listener.accept();
scope (exit) {
writefln("Shutting down and closing the client connection %s",
connection.remoteAddress());
connection.shutdown(SocketShutdown.BOTH);
connection.close();
}
ubyte[1000] buffer;
bool isAllReceived = false;
while (!isAllReceived) {
const received = connection.receive(buffer);
if (received == Socket.ERROR) {
writeln("READ ERROR");
break;
} else {
writefln("Received %s bytes; as string: %s",
received, cast(string)buffer[0..received]);
}
isAllReceived = (received < buffer.length);
}
if (isAllReceived) {
enum header =
"HTTP/1.0 200 OK\nContent-Type: text/html; charset=utf-8\n\n";
string response = header ~ "Hello World!\n";
connection.send(response);
}
}
Thank you,
Ali
More information about the Digitalmars-d-learn
mailing list