Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
June 05, 2011 Receiving data into a type using sockets | ||||
---|---|---|---|---|
| ||||
I'm trying to learn how to do some networking code in D. In C, if I wanted to read 4 bytes into an integer, I could just do (ignoring any error detection): int foo; recv(sockfd, &foo, sizeof(int), 0); How do I do this with D? The receive function takes in a void [] parameter and doesn't take in a number of bytes to read. Is there anyway to accomplish this in D? |
June 05, 2011 Re: Receiving data into a type using sockets | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan Sternberg | On 6/5/11 8:51 PM, Jonathan Sternberg wrote:
> I'm trying to learn how to do some networking code in D. In C, if I wanted to
> read 4 bytes into an integer, I could just do (ignoring any error detection):
>
> int foo;
> recv(sockfd,&foo, sizeof(int), 0);
>
> How do I do this with D? The receive function takes in a void [] parameter and
> doesn't take in a number of bytes to read. Is there anyway to accomplish this
> in D?
auto socket = new Socket(…);
…
int foo;
socket.receive((&foo)[0..1]);
---
void[] is like an array of bytes, with the difference to ubyte[] being that it can contain pointers which must be taken into account by the GC, and implicit convertibility. However, all the socket functions should operate on ubyte[] instead of void[] by current guidelines – the socket module is really old, this will definitely be changed when it will be overhauled/replaced.
David
|
June 05, 2011 Re: Receiving data into a type using sockets | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | Cool. It compiles, but it doesn't seem to be doing exactly what I want. Say I send 2 integers from the server to the client. When I do this on the client, it seems to do the wrong thing. int first, second; auto sock = new TcpSocket(); sock.connect(new InternetAddress("localhost", 10000)); writeln( sock.receive((&first)[0..int.sizeof]) ); writeln( sock.receive((&second)[0..int.sizeof] ); This seems to print 8 and then block on the second call to receive. I thought that D was supposed to recognize that the array was only 4 bytes long and read only that much. (note: on a 32-bit machine, so int comes out to 4 bytes) When I do: writeln( (&first)[0..int.sizeof].length ); It prints 4 as it's supposed to. |
June 05, 2011 Re: Receiving data into a type using sockets | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan Sternberg | On 6/5/11 9:49 PM, Jonathan Sternberg wrote:
> Cool. It compiles, but it doesn't seem to be doing exactly what I want. Say I send
> 2 integers from the server to the client. When I do this on the client, it seems
> to do the wrong thing.
>
> int first, second;
> auto sock = new TcpSocket();
> sock.connect(new InternetAddress("localhost", 10000));
>
> writeln( sock.receive((&first)[0..int.sizeof]) );
> writeln( sock.receive((&second)[0..int.sizeof] );
>
> This seems to print 8 and then block on the second call to receive. I thought that
> D was supposed to recognize that the array was only 4 bytes long and read only
> that much. (note: on a 32-bit machine, so int comes out to 4 bytes)
>
> When I do:
>
> writeln( (&first)[0..int.sizeof].length );
>
> It prints 4 as it's supposed to.
&first is of type int*, so (&first)[0..int.sizeof] returns a slice pointing to int.sizeof (i.e. 4) ints, not a single one as you intend to. Just use »(&first)[0..1]« as per my original reply, and you should be fine.
David
|
June 05, 2011 Re: Receiving data into a type using sockets | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger Attachments:
| On Sun, Jun 5, 2011 at 12:55 PM, David Nadlinger <see@klickverbot.at> wrote:
> On 6/5/11 9:49 PM, Jonathan Sternberg wrote:
>
>> Cool. It compiles, but it doesn't seem to be doing exactly what I want.
>> Say I send
>> 2 integers from the server to the client. When I do this on the client, it
>> seems
>> to do the wrong thing.
>>
>> int first, second;
>> auto sock = new TcpSocket();
>> sock.connect(new InternetAddress("localhost", 10000));
>>
>> writeln( sock.receive((&first)[0..int.sizeof]) );
>> writeln( sock.receive((&second)[0..int.sizeof] );
>>
>> This seems to print 8 and then block on the second call to receive. I
>> thought that
>> D was supposed to recognize that the array was only 4 bytes long and read
>> only
>> that much. (note: on a 32-bit machine, so int comes out to 4 bytes)
>>
>> When I do:
>>
>> writeln( (&first)[0..int.sizeof].length );
>>
>> It prints 4 as it's supposed to.
>>
>
> &first is of type int*, so (&first)[0..int.sizeof] returns a slice pointing
> to int.sizeof (i.e. 4) ints, not a single one as you intend to. Just use
> »(&first)[0..1]« as per my original reply, and you should be fine.
>
Also, note that receive is basically a direct call to C's receive, which
means that it has the same behavior with regards to buffer filling. Calling
sock.receive((&first)[0..1]) returns the number of bytes read, which may be
less than 4. I've handled this in the past by writing a template function
that takes a primitive type and loops until it has read all the bytes it
needs.
Oh, and D's int is always 32 bits, on 32 bit or 64 bit platforms. size_t is
an alias that switches from uint on 32 bit to ulong on 64 bit, and there's
another alias somewhere for signed types (ssize_t, I believe). The primitive
types always have the same sizes until you get into things like cent.
|
Copyright © 1999-2021 by the D Language Foundation