Bug in std.socket
Brad Roberts
braddr at bellevue.puremagic.com
Tue Apr 14 18:30:07 PDT 2009
Your code is inherently racy. The client thread could attempt to connect
before the server thread has finished the steps prior to accept.
Also, there's no second . in the version scheme for DMD, it's just 1.xxx
or 2.xxx.
Later,
Brad
On Tue, 14 Apr 2009, Graham St Jack wrote:
> Forgive my ignorance, but can anyone tell me how to post a ticket for
> phobos?
>
> I want to report a bug in std.socket's TcpSocket.accept() (at least it
> manifests itself there for me) introduced in D 2.0.27 and still there in
> 2.0.28. The following code runs to completion in 2.026 and blocks on
> accept in later compiler versions.
>
>
> import std.socket;
> import std.stdio;
> import core.thread;
>
>
> class Server {
> private {
> InternetAddress mAddress;
> Thread mThread;
> }
>
> this(InternetAddress address) {
> mAddress = address;
> mThread = new Thread(&run);
> mThread.name = "server".dup;
> mThread.start;
> }
>
> void join() {
> mThread.join;
> }
>
> void run() {
> try {
> writefln("server - setting up server socket");
> auto listener = new TcpSocket();
> listener.bind(mAddress);
> listener.listen(5);
>
> // wait for a connection
> writefln("server - waiting for a client connection");
> auto socket = listener.accept();
> writefln("server - got a client connection");
>
> // read some data and write it back
> writefln("server - reading data from the client");
> ubyte[100] data;
> int qty = socket.receive(data);
> writefln("server - writing the data back to the client");
> socket.send(data[0..qty]);
> }
> catch (Exception ex) {
> writefln("server - server got exception: %s", ex);
> }
>
> // terminate
> writefln("server - terminating");
> }
> }
>
> class Client {
> private {
> InternetAddress mAddress;
> Thread mThread;
> }
>
> this(InternetAddress address) {
> mAddress = address;
> mThread = new Thread(&run);
> mThread.name = "client".dup;
> mThread.start;
> }
>
> void join() {
> mThread.join;
> }
>
> void run() {
> try {
> // connect
> writefln("client - connecting to server");
> auto socket = new TcpSocket(mAddress);
> writefln("client - connected to server");
>
> // send and receive some data
> writefln("client - sending data to server");
> ubyte[3] send_data;
> send_data[0] = 41;
> send_data[1] = 42;
> send_data[2] = 43;
> int qty = socket.send(send_data);
> assert(qty == send_data.length);
> writefln("client - receiving data from server");
> ubyte[100] receive_data;
> qty = socket.receive(receive_data);
> writefln("client - got %s bytes from server", qty);
> }
> catch (Exception ex) {
> writefln("client - client got exception %s", ex);
> }
>
> // terminate
> writefln("client - terminating");
> }
> }
>
>
>
> int main(string[] args) {
> writefln("test starting");
>
> try {
> InternetAddress address = new InternetAddress("localhost", 12345);
> Server server = new Server(address);
> Client client = new Client(address);
> writefln("joining with server");
> server.join;
> writefln("joining with client");
> client.join;
> writefln("finished");
> }
> catch (Exception ex) {
> writefln("unexpected exception %s", ex);
> }
> return 0;
> }
>
More information about the Digitalmars-d
mailing list