Permalink
Browse files

Add server sockets to socket test module

  • Loading branch information...
1 parent e441498 commit 7ff1b8e631045135cc0735d013ebf9a51bceadc3 @sorear committed Aug 21, 2012
Showing with 69 additions and 49 deletions.
  1. +53 −49 examples/sock.pl
  2. +16 −0 lib/Builtins.cs
View
@@ -1,28 +1,29 @@
class IO::Socket::INET {
has $!sock;
- #has Buf $!buf;
-
- #method recv (Cool $chars = Inf) {
- # die('Socket not available') unless $!sock;
-
- # if $!buffer.chars < $chars {
- # my str $r = $!sock.recv;
- # $r = pir::trans_encoding__SSI($r,
- # pir::find_encoding__Is('utf8'));
- # $!buffer ~= nqp::p6box_s($r);
- # }
-
- # if $!buffer.chars > $chars {
- # my $rec = $!buffer.substr(0, $chars);
- # $!buffer = $!buffer.substr($chars);
- # $rec
- # } else {
- # my $rec = $!buffer;
- # $!buffer = '';
- # $rec;
- # }
- #}
+ has Str $!buffer = '';
+
+ # TODO: This code is horribly broken, especially if a character gets cut by
+ # a buffer or packet boundry, or you want to switch from char to binary mode
+ # doing it right seems to require some kind of Decoder class
+
+ method recv (Cool $chars = Inf) {
+ die('Socket not available') unless $!sock;
+
+ if $!buffer.chars < $chars {
+ $!buffer ~= self.read(2048).decode('UTF-8');
+ }
+
+ if $!buffer.chars > $chars {
+ my $rec = $!buffer.substr(0, $chars);
+ $!buffer = $!buffer.substr($chars);
+ $rec
+ } else {
+ my $rec = $!buffer;
+ $!buffer = '';
+ $rec;
+ }
+ }
method read(IO::Socket::INET:D: Cool $bufsize) {
die('Socket not available') unless $!sock;
@@ -124,12 +125,11 @@
#If Listen is defined then a listen socket is created, else if the socket type,
#which is derived from the protocol, is SOCK_STREAM then connect() is called.
if $.listen || $.localhost || $.localport {
- #my $addr := $sock.sockaddr($.localhost || "0.0.0.0", $.localport || 0);
- #$sock.bind($addr);
+ Q:CgOp { (rnull (socket_bind (unbox socket {$!sock}) (unbox str {$.localhost || "0.0.0.0"}) (unbox int {$.localport || 0}))) };
}
if $.listen {
- #$sock.listen($.listen);
+ Q:CgOp { (rnull (socket_listen (unbox socket {$!sock}) (unbox int {20}))) };
}
elsif $.type == sock::SOCK_STREAM {
Q:CgOp { (rnull (socket_connect (unbox socket {$!sock}) (unbox str {$.host}) (unbox int {$.port}))) };
@@ -138,29 +138,31 @@
self;
}
- #method get() {
- # ++$!ins;
- # my str $line = nqp::getattr(self, $?CLASS, '$!sock').readline(nqp::unbox_s($!input-line-separator));
- # my str $sep = $!input-line-separator;
- # my int $len = nqp::chars($line);
- # my int $sep-len = nqp::chars($sep);
- # $len >= $sep-len && nqp::substr($line, $len - $sep-len) eq nqp::unbox_s($sep)
- # ?? nqp::p6box_s(nqp::substr($line, 0, $len - $sep-len))
- # !! nqp::p6box_s($line);
- #}
+ method get() {
+ ++$!ins;
+ my $inbuf = '';
+ my $irs = $!input-line-separator;
+ my $irslen = chars($irs);
+ until substr($inbuf, chars($inbuf)-$irslen, $irslen) eq $irs {
+ $inbuf ~= (self.recv(1) || return $inbuf);
+ }
+ substr($inbuf, 0, chars($inbuf)-$irslen);
+ }
- #method lines() {
- # gather { take self.get() };
- #}
+ method lines() {
+ gather { take self.get() };
+ }
- #method accept() {
- # #my $new_sock := nqp::create($?CLASS);
- # ## A solution as proposed by moritz
- # my $new_sock := $?CLASS.bless(*, :$!family, :$!proto, :$!type);
- # nqp::getattr($new_sock, $?CLASS, '$!buffer') = '';
- # nqp::bindattr($new_sock, $?CLASS, '$!sock', nqp::getattr(self, $?CLASS, '$!sock').accept());
- # return $new_sock;
- #}
+ method !setsock($ns) {
+ $!sock = $ns;
+ $!buffer = '';
+ self;
+ }
+
+ method accept() {
+ my $new_sock := self.WHAT.bless(*, :$!family, :$!proto, :$!type);
+ $new_sock!setsock( Q:CgOp { (box Any (socket_accept (unbox socket {$!sock}))) } );
+ }
#method remote_address() {
# return nqp::p6box_s(nqp::getattr(self, $?CLASS, '$!sock').remote_address());
@@ -171,6 +173,8 @@
#}
}
-my $sock = IO::Socket::INET.new( host => 'perl6.org', port => 80 );
-$sock.send("GET / HTTP/1.0\cJ\cM\cJ\cM");
-say $sock.read(16384).decode('UTF-8');
+my $sock = IO::Socket::INET.new( localport => 9999, :listen );
+while $sock.accept -> $new {
+ say "<< $new.get() >>";
+ $new.close;
+}
View
@@ -2960,4 +2960,20 @@ public class Blackhole : Variable {
public static void socket_connect(Socket sock, string host, int port) {
sock.Connect(host, port);
}
+
+ public static void socket_bind(Socket sock, string host, int port) {
+ System.Net.IPAddress addr;
+ if (host.Length == 0 || !System.Net.IPAddress.TryParse (host, out addr))
+ addr = System.Net.Dns.GetHostEntry (host).AddressList[0];
+
+ sock.Bind(new System.Net.IPEndPoint(addr, port));
+ }
+
+ public static void socket_listen(Socket sock, int log) {
+ sock.Listen(log);
+ }
+
+ public static Socket socket_accept(Socket sock) {
+ return sock.Accept();
+ }
}

0 comments on commit 7ff1b8e

Please sign in to comment.