Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
April 04, 2010 Socket and SocketStream | ||||
---|---|---|---|---|
| ||||
I'm trying a bit of socket stuff. I went back to the htmlget.d sample, and patched it up for 2.0 (I'm using DMD 2.042 on Ubuntu 9.10). I get the same results from this as I do from my own code, which is that writeString() on the SocketStream throws an exception. From everything I can tell, I don't have an established connection, even though everything claims I have one. Here is the updated sample code: /* HTMLget written by Christopher E. Miller This code is public domain. You may use it for any purpose. This code has no warranties and is provided 'as-is'. */ //debug = HTMLGET; module htmlget; import std.string, std.conv, std.stream; import std.socket, std.socketstream; import std.stdio; int main(string[] args) { uint addr; if(args.length < 2) { printf("Usage:\n htmlget <web-page>\n"); return 0; } string url = args[1]; int i; //i = std.string.find(url, "://"); i=std.string.indexOf(url,"://"); if(i != -1) { if(icmp(url[0 .. i], "http")) throw new Exception("http:// expected"); } url = url[i+3 .. url.length]; //i = std.string.find(url, '#'); i=std.string.indexOf(url,'#'); if(i != -1) // Remove anchor ref. url = url[0 .. i]; //i = std.string.find(url, '/'); i=std.string.indexOf(url,'/'); string domain; if(i == -1) { domain = url; url = "/"; } else { domain = url[0 .. i]; url = url[i .. url.length]; } ushort port; //i = std.string.find(domain, ':'); i = std.string.indexOf(domain,':'); if(i == -1) { port = 80; // Default HTTP port. } else { port=parse!(ushort)(domain[i+1..domain.length]); domain = domain[0 .. i]; } writefln("Parsed domain: %s, port: %d and url: %s", domain, port, url); addr = InternetAddress.parse(domain); debug(HTMLGET) writefln("Connecting to %s on port %d...", domain, port); auto Socket sock = new TcpSocket(new std.socket.InternetAddress(addr/*domain*/, port)); Stream ss = new SocketStream(sock); debug(HTMLGET) printf("Connected!\nRequesting URL \"" ~ url ~ "\"...\n"); if(port != 80) { char[] temp=cast(char[]) domain; temp=temp~cast(char[])":" ~cast(char[]) (to!string(port)); domain=cast(string)temp; } ss.writeString("GET " ~ url ~ " HTTP/1.1\r\n" "Host: " ~ domain ~ "\r\n" "\r\n"); // Skip HTTP header. string line; for(;;) { line = cast(string)ss.readLine(); if(!line.length) break; const string CONTENT_TYPE_NAME = "Content-Type: "; if(line.length > CONTENT_TYPE_NAME.length && !icmp(CONTENT_TYPE_NAME, line[0 .. CONTENT_TYPE_NAME.length])) { string type; type = line[CONTENT_TYPE_NAME.length .. line.length]; if(type.length <= 5 || icmp("text/", type[0 .. 5])) throw new Exception("URL is not text"); } } print_lines: while(!ss.eof()) { line = cast(string)ss.readLine(); printf("%.*s\n", line); size_t iw; for(iw = 0; iw != line.length; iw++) { if(!icmp("</html>", line[iw .. line.length])) break print_lines; } } return 0; } And here is my invocation, and its response: $ dmd -run ./htmlget2.d http://10.120.1.106:80/ Parsed domain: 10.120.1.106, port: 80 and url: / std.stream.WriteException: unable to write to stream $ Can anyone else duplicate this? Or let me know if I'm doing something wrong in my updating of the sample code? |
April 06, 2010 Re: Socket and SocketStream | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kyle Mallory | I hate replying to my own thead. :-(
I was able to compile listener.d, and connect successfully to it via telnet., so I know at least the listener stuff so working.
However, stepping down to an even simpler example, I can't even get the following code to establish a connection:
import std.socket;
void main(string[] args) {
Socket s = new TcpSocket(new InternetAddress(args[1], parse!(ushort)(args[2])));
assert(s.isAlive);
s.close();
}
Connecting against listener.d, I should at least see a "connection from" and a "disconnected". But nothing happens. No error messages, no exceptions, etc.
Am I the only one with this problem?
On 04/04/2010 11:36 AM, Kyle Mallory wrote:
> I'm trying a bit of socket stuff. I went back to the htmlget.d sample,
> and patched it up for 2.0 (I'm using DMD 2.042 on Ubuntu 9.10). I get
> the same results from this as I do from my own code, which is that
> writeString() on the SocketStream throws an exception.
>
> From everything I can tell, I don't have an established connection,
> even though everything claims I have one.
>
> Here is the updated sample code:
>
> /*
> HTMLget written by Christopher E. Miller
> This code is public domain.
> You may use it for any purpose.
> This code has no warranties and is provided 'as-is'.
> */
>
>
> //debug = HTMLGET;
>
>
> module htmlget;
> import std.string, std.conv, std.stream;
> import std.socket, std.socketstream;
> import std.stdio;
>
> int main(string[] args)
> {
> uint addr;
> if(args.length < 2)
> {
> printf("Usage:\n htmlget <web-page>\n");
> return 0;
> }
> string url = args[1];
> int i;
>
> //i = std.string.find(url, "://");
> i=std.string.indexOf(url,"://");
> if(i != -1)
> {
> if(icmp(url[0 .. i], "http"))
> throw new Exception("http:// expected");
> }
>
> url = url[i+3 .. url.length];
>
> //i = std.string.find(url, '#');
> i=std.string.indexOf(url,'#');
> if(i != -1) // Remove anchor ref.
> url = url[0 .. i];
>
> //i = std.string.find(url, '/');
> i=std.string.indexOf(url,'/');
> string domain;
> if(i == -1)
> {
> domain = url;
> url = "/";
> }
> else
> {
> domain = url[0 .. i];
> url = url[i .. url.length];
> }
>
> ushort port;
> //i = std.string.find(domain, ':');
> i = std.string.indexOf(domain,':');
> if(i == -1)
> {
> port = 80; // Default HTTP port.
> }
> else
> {
> port=parse!(ushort)(domain[i+1..domain.length]);
> domain = domain[0 .. i];
> }
>
> writefln("Parsed domain: %s, port: %d and url: %s", domain, port, url);
>
> addr = InternetAddress.parse(domain);
> debug(HTMLGET)
> writefln("Connecting to %s on port %d...", domain, port);
>
> auto Socket sock = new TcpSocket(new
> std.socket.InternetAddress(addr/*domain*/, port));
> Stream ss = new SocketStream(sock);
>
> debug(HTMLGET)
> printf("Connected!\nRequesting URL \"" ~ url ~ "\"...\n");
>
> if(port != 80)
> {
> char[] temp=cast(char[]) domain;
> temp=temp~cast(char[])":" ~cast(char[]) (to!string(port));
> domain=cast(string)temp;
> }
> ss.writeString("GET " ~ url ~ " HTTP/1.1\r\n"
> "Host: " ~ domain ~ "\r\n"
> "\r\n");
>
> // Skip HTTP header.
> string line;
> for(;;)
> {
> line = cast(string)ss.readLine();
> if(!line.length)
> break;
>
> const string CONTENT_TYPE_NAME = "Content-Type: ";
> if(line.length > CONTENT_TYPE_NAME.length &&
> !icmp(CONTENT_TYPE_NAME, line[0 .. CONTENT_TYPE_NAME.length]))
> {
> string type;
> type = line[CONTENT_TYPE_NAME.length .. line.length];
> if(type.length <= 5 || icmp("text/", type[0 .. 5]))
> throw new Exception("URL is not text");
> }
> }
>
> print_lines:
> while(!ss.eof())
> {
> line = cast(string)ss.readLine();
> printf("%.*s\n", line);
>
> size_t iw;
> for(iw = 0; iw != line.length; iw++)
> {
> if(!icmp("</html>", line[iw .. line.length]))
> break print_lines;
> }
> }
>
> return 0;
> }
>
>
> And here is my invocation, and its response:
>
> $ dmd -run ./htmlget2.d http://10.120.1.106:80/
> Parsed domain: 10.120.1.106, port: 80 and url: /
> std.stream.WriteException: unable to write to stream
> $
>
>
> Can anyone else duplicate this? Or let me know if I'm doing something
> wrong in my updating of the sample code?
>
>
|
April 06, 2010 Re: Socket and SocketStream | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kyle Mallory | I believe you are running into this bug: http://d.puremagic.com/issues/show_bug.cgi?id=2835 Where sockets don't work in Linux. |
April 06, 2010 Re: Socket and SocketStream | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On 04/05/2010 06:56 PM, Jesse Phillips wrote:
> I believe you are running into this bug:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=2835
>
> Where sockets don't work in Linux.
Argh.. Thanks. Looks like an easy enough patch. Unfortunate the bug its still lingering in the latest build (especially considering that a patch is provided).
I guess the next step is figuring out how to rebuild the phobos library.
Thanks.
|
April 06, 2010 Re: Socket and SocketStream | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On 04/05/2010 06:56 PM, Jesse Phillips wrote:
> I believe you are running into this bug:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=2835
>
> Where sockets don't work in Linux.
Thank you, Jesse! Applied the patch, recompiled libdruntime.a and libphobos2.a and everything is working as expected!
Very much appreciated!
Kyle
|
Copyright © 1999-2021 by the D Language Foundation