Quantcast

Reading from a socket

classic Classic list List threaded Threaded
49 messages Options
123
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Reading from a socket

citron
Hi,

The code found here is writing to a socket.

s = new Socket("localhost", 8167);
s << "Why don't you call me anymore?\n"
s.close()

How can I read the response from the socket?

Thanks!

Hotmail: Trusted email with Microsoft’s powerful SPAM protection. Sign up now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 12 March 2010 09:32, Anders Viklund <[hidden email]> wrote:
> Hi,
>
> The code found here is writing to a socket.
>
> s = new Socket("localhost", 8167);
> s << "Why don't you call me anymore?\n"
> s.close()

s.withStreams { inStream, outStream ->
    def reader = inStream.newReader()
    def name = reader.readLine()
    outStream << "Hello ${name}"
}

...  one of my favourite examples of closures leading to neat idioms.

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
I am trying to pipe an input stream into the socket, but it never closes.

 server = new ServerSocket(8182)
 while(true) {
     server.accept() { socket ->
         socket.withStreams { input, output ->
         def s = new Socket("localhost", 9090)
         s << input       // < -- program hangs here, why?


Thanks for any ideas how to solve this!



> Date: Fri, 12 Mar 2010 10:10:37 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 12 March 2010 09:32, Anders Viklund <[hidden email]> wrote:
> > Hi,
> >
> > The code found here is writing to a socket.
> >
> > s = new Socket("localhost", 8167);
> > s << "Why don't you call me anymore?\n"
> > s.close()
>
> s.withStreams { inStream, outStream ->
> def reader = inStream.newReader()
> def name = reader.readLine()
> outStream << "Hello ${name}"
> }
>
> ... one of my favourite examples of closures leading to neat idioms.
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Free, trusted and rich email service. Get it now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 12 March 2010 20:27, Anders Viklund <[hidden email]> wrote:
> I am trying to pipe an input stream into the socket, but it never closes.
>
>  server = new ServerSocket(8182)
>  while(true) {
>      server.accept() { socket ->
>          socket.withStreams { input, output ->
>          def s = new Socket("localhost", 9090)
>          s << input       // < -- program hangs here, why?

Basically, I don't think the Socket.leftShift() function does what you
want, with an inputStream as an argument.

Instead I think you need a loop that reads from input and writes to s.

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
well, the data arrives to its target destination, but the stream never closes, thats the problem.

Why shouldnt leftShift work in this case?


> Date: Fri, 12 Mar 2010 21:31:09 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 12 March 2010 20:27, Anders Viklund <[hidden email]> wrote:
> > I am trying to pipe an input stream into the socket, but it never closes.
> >
> >  server = new ServerSocket(8182)
> >  while(true) {
> >      server.accept() { socket ->
> >          socket.withStreams { input, output ->
> >          def s = new Socket("localhost", 9090)
> >          s << input       // < -- program hangs here, why?
>
> Basically, I don't think the Socket.leftShift() function does what you
> want, with an inputStream as an argument.
>
> Instead I think you need a loop that reads from input and writes to s.
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Trusted email with Microsoft’s powerful SPAM protection. Sign up now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 12 March 2010 22:08, Anders Viklund <[hidden email]> wrote:
> well, the data arrives to its target destination, but the stream never
> closes, thats the problem.
>
> Why shouldnt leftShift work in this case?

Ah, I was going by the JavaDoc for Socket, which doesn't really
specify what leftShift(Object) does in detail:
"Overloads the left shift operator to provide an append mechanism to
add things to the output stream of a socket"
That doesn't document the fairly specialised case of an InputStream.
Could do better!

Without any documented semantics for leftShift(InputStream), I don't
know what you're trying to do, nor whether it should work.

Does the InputStream eventually signal EOF? It would seem reasonable
for leftShift() to return only when that happens. But again, nothing
*says* that it will. At least not in the JavaDoc.

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
I am trying to create a http proxy, just like tcpmon.

So far I have managed to get the request through to its destination.
Then it stalls because it never stops reading from the request input stream.


> Date: Sat, 13 Mar 2010 07:33:53 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 12 March 2010 22:08, Anders Viklund <[hidden email]> wrote:
> > well, the data arrives to its target destination, but the stream never
> > closes, thats the problem.
> >
> > Why shouldnt leftShift work in this case?
>
> Ah, I was going by the JavaDoc for Socket, which doesn't really
> specify what leftShift(Object) does in detail:
> "Overloads the left shift operator to provide an append mechanism to
> add things to the output stream of a socket"
> That doesn't document the fairly specialised case of an InputStream.
> Could do better!
>
> Without any documented semantics for leftShift(InputStream), I don't
> know what you're trying to do, nor whether it should work.
>
> Does the InputStream eventually signal EOF? It would seem reasonable
> for leftShift() to return only when that happens. But again, nothing
> *says* that it will. At least not in the JavaDoc.
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Trusted email with powerful SPAM protection. Sign up now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 13 March 2010 08:20, Anders Viklund <[hidden email]> wrote:
> I am trying to create a http proxy, just like tcpmon.
>
> So far I have managed to get the request through to its destination.
> Then it stalls because it never stops reading from the request input stream.

And how would it know to stop reading from the inputstream, unless you
call a method that

So, do a loop. It's only using Java stuff; no Groovy tricks, but it's
simple and it works.

byte[] buffer
def len = input.read(buffer)
while(len >=0) {
    output.write(buffer,0,len)
    len = input.read(buffer)
}

Of course you probably also want to do the same to transmit data in
the opposite direction. You could do this in another thread:
   // Wrap the code above in a StreamForwarder class that implements Runnable.
   Thread c2s = new Thread(new StreamForwarder(clientInStream,serverOutStream));
   StreamForwarder s2c = new StreamForwarder(serverInStream,clientOutStream);
   // Run one in a new thread
   2s.start();
   // Run the other in this thread
   s2c.run();

Or you could read up on select() and do it all in one thread.
Potentially better scalability. Arguably less easy for people to
understand, if they later read the code and are not familiar with
select().


--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
Hmm, its still not working.

byte[] buffer
def len = input.read(buffer) // <-- now its stalling here, why?
while(len >=0) {
 output.write(buffer,0,len)
 len = input.read(buffer)
}

> Date: Sat, 13 Mar 2010 08:46:21 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 13 March 2010 08:20, Anders Viklund <[hidden email]> wrote:
> > I am trying to create a http proxy, just like tcpmon.
> >
> > So far I have managed to get the request through to its destination.
> > Then it stalls because it never stops reading from the request input stream.
>
> And how would it know to stop reading from the inputstream, unless you
> call a method that
>
> So, do a loop. It's only using Java stuff; no Groovy tricks, but it's
> simple and it works.
>
> byte[] buffer
> def len = input.read(buffer)
> while(len >=0) {
> output.write(buffer,0,len)
> len = input.read(buffer)
> }
>
> Of course you probably also want to do the same to transmit data in
> the opposite direction. You could do this in another thread:
> // Wrap the code above in a StreamForwarder class that implements Runnable.
> Thread c2s = new Thread(new StreamForwarder(clientInStream,serverOutStream));
> StreamForwarder s2c = new StreamForwarder(serverInStream,clientOutStream);
> // Run one in a new thread
> 2s.start();
> // Run the other in this thread
> s2c.run();
>
> Or you could read up on select() and do it all in one thread.
> Potentially better scalability. Arguably less easy for people to
> understand, if they later read the code and are not familiar with
> select().
>
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Powerful Free email with security by Microsoft. Get it now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 13 March 2010 09:38, Anders Viklund <[hidden email]> wrote:

> def len = input.read(buffer) // <-- now its stalling here, why?

http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[])

"This method blocks until input data is available, end of file is
detected, or an exception is thrown."

So, it's waiting for the other end to either write to the socket, or close it.

It seems as if by trying to write a proxy, you're running before you
can walk. Go through the Java sockets tutorials.
http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
Write a simple client/server pair and make sure you understand how it works.

Groovy doesn't change anything much, other than give you a few
convenience methods for common cases (such as
ServerSocket.accept(Closure ) and Socket.withStreams(Closure)

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
Thanks for the link to the java socket documentation!

This is so wierd,

here, the request gets forwarded to the server, but the the client never sends an end of file character in the stream so it stalls.

 def server = new ServerSocket(8226)
 while(true) {
     server.accept() { socket ->
        socket.withStreams { input, output ->
            def s = new Socket("localhost", 9090)
            println "Received request ok"
            s << input
...

but, if I do like this, the request does not even get forwarded to the server, why?

 def server = new ServerSocket(8226)
 while(true) {
     server.accept() { socket ->
        socket.withStreams { input, output ->
            def s = new Socket("localhost", 9090)
            println "Received request ok"
            def thRequest = Thread.start {
                 s << input
              }

..



> Date: Sat, 13 Mar 2010 10:27:20 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 13 March 2010 09:38, Anders Viklund <[hidden email]> wrote:
>
> > def len = input.read(buffer) // <-- now its stalling here, why?
>
> http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[])
>
> "This method blocks until input data is available, end of file is
> detected, or an exception is thrown."
>
> So, it's waiting for the other end to either write to the socket, or close it.
>
> It seems as if by trying to write a proxy, you're running before you
> can walk. Go through the Java sockets tutorials.
> http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
> Write a simple client/server pair and make sure you understand how it works.
>
> Groovy doesn't change anything much, other than give you a few
> convenience methods for common cases (such as
> ServerSocket.accept(Closure ) and Socket.withStreams(Closure)
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Free, trusted and rich email service. Get it now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
Putting the left shift into a try/catch results in this exception

java.net.SocketException: socket closed

Why is this?

 def server = new ServerSocket(8235)
 while(true) {
     server.accept() { socket ->
        socket.withStreams { input, output ->
            def s = new Socket("localhost", 9090)                       
            s.withStreams { inStream, outStream ->
               def thRequest = Thread.start {
                   try{
                      outStream << input
                   }catch (Exception e){println e}
               }
            }
        }      
     }
 }



From: [hidden email]
To: [hidden email]
Date: Sat, 13 Mar 2010 11:09:41 +0000
Subject: RE: [groovy-user] Reading from a socket

Thanks for the link to the java socket documentation!

This is so wierd,

here, the request gets forwarded to the server, but the the client never sends an end of file character in the stream so it stalls.

 def server = new ServerSocket(8226)
 while(true) {
     server.accept() { socket ->
        socket.withStreams { input, output ->
            def s = new Socket("localhost", 9090)
            println "Received request ok"
            s << input
...

but, if I do like this, the request does not even get forwarded to the server, why?

 def server = new ServerSocket(8226)
 while(true) {
     server.accept() { socket ->
        socket.withStreams { input, output ->
            def s = new Socket("localhost", 9090)
            println "Received request ok"
            def thRequest = Thread.start {
                 s << input
              }

..



> Date: Sat, 13 Mar 2010 10:27:20 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 13 March 2010 09:38, Anders Viklund <[hidden email]> wrote:
>
> > def len = input.read(buffer) // <-- now its stalling here, why?
>
> http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[])
>
> "This method blocks until input data is available, end of file is
> detected, or an exception is thrown."
>
> So, it's waiting for the other end to either write to the socket, or close it.
>
> It seems as if by trying to write a proxy, you're running before you
> can walk. Go through the Java sockets tutorials.
> http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
> Write a simple client/server pair and make sure you understand how it works.
>
> Groovy doesn't change anything much, other than give you a few
> convenience methods for common cases (such as
> ServerSocket.accept(Closure ) and Socket.withStreams(Closure)
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Free, trusted and rich email service. Get it now.

Hotmail: Trusted email with Microsoft’s powerful SPAM protection. Sign up now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 13 March 2010 11:48, Anders Viklund <[hidden email]> wrote:
> Putting the left shift into a try/catch results in this exception
>
> java.net.SocketException: socket closed
>
> Why is this?

Because one of your sockets is closed. Since you've bundled the read
and the write into one statement, and you've thrown away the stack
trace, it's not possible to tell which one. Either the client has
closed the socket you're reading from, or the server has closed the
socket you're writing to. Your code is going to have to deal with
that, and it cannot assume that they'll happen in a particular order.

Use e.printStackTrace(), and stop desperately clinging onto your
desire to use '<<', since nobody who's prepared to comment at this
time, knows how it's supposed to behave.

I don't understand why you didn't see this exception until you
explicitly caught it. Are you working in some wider environment that
catches and ignores exceptions? Or did you just fail to tell us about
the exceptions when they were reported?

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to setup the JAVA_OPTS in groovy?

hix li
In reply to this post by citron
I would like to allocate more memory for running groovy.
 
Is it by changing the JAVA_OPTS?
I have changed the groovy/bin/startGroovy.bat file, placing the command:

set JAVA_OPTS="-Xmx512m"
 
But the resource monitor tells that only 55M is allocated to groovy when it's running in windows.
 
Is there any other place that I should make change in order to allocate more memory for running groovy?
 
Thanks!
 
Hix
 
 


Yahoo! Canada Toolbar : Search from anywhere on the web and bookmark your favourite sites. Download it now!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
In reply to this post by John Hartnup
I am running the code in the GroovyConsole.

I have selected "Capture Standard Output" and "Show Full Stack Traces" under view tab in the console and I am also surprised that no errors were printed to the console until I used try/catch.


The reason why I am using << is that I can see that the target server can receive the request ok and its less code to write.

Anyway, here is the full stack trace.

java.net.SocketException: socket closed
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:129)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.leftShift(DefaultGroovyMethods.java:5011)
        at org.codehaus.groovy.runtime.dgm$304.invoke(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:270)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:43)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
        at HttpProxy3$_run_closure1_closure2_closure3_closure4.doCall(HttpProxy3.groovy:9)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:142)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:150)
        at HttpProxy3$_run_closure1_closure2_closure3_closure4.doCall(HttpProxy3.groovy)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)
        at groovy.lang.Closure.call(Closure.java:279)
        at groovy.lang.Closure.call(Closure.java:274)
        at groovy.lang.Closure.run(Closure.java:355)
        at java.lang.Thread.run(Thread.java:619)

> Date: Sat, 13 Mar 2010 11:59:55 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 13 March 2010 11:48, Anders Viklund <[hidden email]> wrote:
> > Putting the left shift into a try/catch results in this exception
> >
> > java.net.SocketException: socket closed
> >
> > Why is this?
>
> Because one of your sockets is closed. Since you've bundled the read
> and the write into one statement, and you've thrown away the stack
> trace, it's not possible to tell which one. Either the client has
> closed the socket you're reading from, or the server has closed the
> socket you're writing to. Your code is going to have to deal with
> that, and it cannot assume that they'll happen in a particular order.
>
> Use e.printStackTrace(), and stop desperately clinging onto your
> desire to use '<<', since nobody who's prepared to comment at this
> time, knows how it's supposed to behave.
>
> I don't understand why you didn't see this exception until you
> explicitly caught it. Are you working in some wider environment that
> catches and ignores exceptions? Or did you just fail to tell us about
> the exceptions when they were reported?
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Free, trusted and rich email service. Get it now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: How to setup the JAVA_OPTS in groovy?

citron
In reply to this post by hix li
I guess the Xms is the maximum heap size to use, not the initial heap size.

see here:
http://jmol.sourceforge.net/docs/JmolUserGuide/ch02s07.html


Date: Sat, 13 Mar 2010 04:01:55 -0800
From: [hidden email]
To: [hidden email]
CC: [hidden email]
Subject: [groovy-user] How to setup the JAVA_OPTS in groovy?

I would like to allocate more memory for running groovy.
 
Is it by changing the JAVA_OPTS?
I have changed the groovy/bin/startGroovy.bat file, placing the command:

set JAVA_OPTS="-Xmx512m"
 
But the resource monitor tells that only 55M is allocated to groovy when it's running in windows.
 
Is there any other place that I should make change in order to allocate more memory for running groovy?
 
Thanks!
 
Hix
 
 


Yahoo! Canada Toolbar : Search from anywhere on the web and bookmark your favourite sites. Download it now!



Hotmail: Free, trusted and rich email service. Get it now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
In reply to this post by citron
So, the only important part of the stack trace is the first few lines:

> java.net.SocketException: socket closed
>         at java.net.SocketInputStream.socketRead0(Native Method)
>         at java.net.SocketInputStream.read(SocketInputStream.java:129)
>         at org.codehaus.groovy.runtime.DefaultGroovyMethods.leftShift(DefaultGroovyMethods.java:5011)

Which of your two sockets do you think that applies to (there is
enough info there to tell)
What do you think the state of that socket is when the read happens?
(the exception message tells you)
How do you want your proxy to behave when that state occurs? (this is
your implementation decision)

Note: "less code" is great, but only if it does what you need it to!

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
I guess its the left shift thats causing this problem.

But why is the exception thrown for left shift inside the thread and not outside?


> Date: Sat, 13 Mar 2010 12:30:53 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> So, the only important part of the stack trace is the first few lines:
>
> > java.net.SocketException: socket closed
> >         at java.net.SocketInputStream.socketRead0(Native Method)
> >         at java.net.SocketInputStream.read(SocketInputStream.java:129)
> >         at org.codehaus.groovy.runtime.DefaultGroovyMethods.leftShift(DefaultGroovyMethods.java:5011)
>
> Which of your two sockets do you think that applies to (there is
> enough info there to tell)
> What do you think the state of that socket is when the read happens?
> (the exception message tells you)
> How do you want your proxy to behave when that state occurs? (this is
> your implementation decision)
>
> Note: "less code" is great, but only if it does what you need it to!
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. Sign up now.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Reading from a socket

John Hartnup
On 13 March 2010 12:36, Anders Viklund <[hidden email]> wrote:
> I guess its the left shift thats causing this problem.
>
> But why is the exception thrown for left shift inside the thread and not
> outside?

I just reproduced it using a simpler case (always a good idea).

When you think it through, it makes sense.

What does withStreams() do?

A1. Get a pair of Input/Output streams from the socket
A2. Pass the streams to the closure provided as a parameter
A3. When the closure returns, close the streams (and therefore the socket)

Now, what does your closure do:
B1. spawns a thread
B2. returns

... and within the thread:
C1. Try to read from the InputStream
...

What you're seeing is that A3 happens while C1 is in progress. So C1
gets the socket closed exception.

To avoid this, you need a wait() for the thread to complete, before
your withStreams closure returns.

Here's some Java I have lying around. It will probably work as-is
within Groovy. I see no reason to change it.

        public void blindlyForward() {
                Thread c2s = new Thread(new StreamForwarder(clientInStream,serverOutStream));
                StreamForwarder s2c = new StreamForwarder(serverInStream,clientOutStream);
               
                // Run one in a new thread
                c2s.start();
                // Run the other in this thread
                s2c.run();
               
               
                boolean done = false;
                while(!done) {
                        try {
                                c2s.join();
                                done = true;
                        } catch (InterruptedException e) {
                                // Shouldn't happen. Thread has no wait() or sleep() calls.
                                System.out.println(e.getMessage());
                        }
                }
        }

... and StreamForwarder itself:

public class StreamForwarder implements Runnable {
       
        private InputStream input;
        private OutputStream output;
       
        public static final int BLOCKSIZE = 1024;

        /**
         * Constructor
         * @param input Something to read from
         * @param output Something to write to
         */
        public StreamForwarder(InputStream input, OutputStream output) {
                this.input = input;
                this.output = output;
        }
       
        /**
         * Run method - read a KB, write a KB, until either an IOException is thrown
         * or we reach EOF.
         */
        public void run() {
                byte[] block = new byte[BLOCKSIZE];
                boolean done = false;
                while(!done) {
                        try {
                                int size = input.read(block);
                                if(size >0) {
                                        output.write(block,0,size);
                                }
                                if(size == -1) {
                                        done = true;
                                }
                        } catch (IOException e) {
                                System.err.println(e.getMessage());
                                done = true;
                        }
                        Thread.yield(); // polite, but surely redundant in this day and age?
                }
        }
}

--
"There is no way to peace; peace is the way"

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Reading from a socket

citron
Excellent John!

This is now working, now I just have to figure out how to copy the input/output streams into separate strings on their way through.

 def server = new ServerSocket(8235)
 while(true) {
     server.accept() { socket ->
        socket.withStreams { input, output ->
            def s = new Socket("localhost", 9090)                       
            s.withStreams { inStream, outStream ->
                try{
                 blindlyForward(inStream, output,input, outStream)
                }catch(Exception e){e.printStackStrace()}
            }
        }      
     }
 }
 
 
 public void blindlyForward(InputStream clientInStream, OutputStream serverOutStream, InputStream serverInStream, OutputStream clientOutStream) {
        Thread c2s = new Thread(new StreamForwarder(clientInStream,serverOutStream));
        StreamForwarder s2c = new StreamForwarder(serverInStream,clientOutStream);
       
        // Run one in a new thread
        c2s.start();
        // Run the other in this thread
        s2c.run();
       
       
        boolean done = false;
        while(!done) {
            try {
                c2s.join();
                done = true;
            } catch (InterruptedException e) {
                // Shouldn't happen. Thread has no wait() or sleep() calls.
                System.out.println(e.getMessage());
            }
        }
}

> Date: Sat, 13 Mar 2010 13:14:12 +0000
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Reading from a socket
>
> On 13 March 2010 12:36, Anders Viklund <[hidden email]> wrote:
> > I guess its the left shift thats causing this problem.
> >
> > But why is the exception thrown for left shift inside the thread and not
> > outside?
>
> I just reproduced it using a simpler case (always a good idea).
>
> When you think it through, it makes sense.
>
> What does withStreams() do?
>
> A1. Get a pair of Input/Output streams from the socket
> A2. Pass the streams to the closure provided as a parameter
> A3. When the closure returns, close the streams (and therefore the socket)
>
> Now, what does your closure do:
> B1. spawns a thread
> B2. returns
>
> ... and within the thread:
> C1. Try to read from the InputStream
> ...
>
> What you're seeing is that A3 happens while C1 is in progress. So C1
> gets the socket closed exception.
>
> To avoid this, you need a wait() for the thread to complete, before
> your withStreams closure returns.
>
> Here's some Java I have lying around. It will probably work as-is
> within Groovy. I see no reason to change it.
>
> public void blindlyForward() {
> Thread c2s = new Thread(new StreamForwarder(clientInStream,serverOutStream));
> StreamForwarder s2c = new StreamForwarder(serverInStream,clientOutStream);
>
> // Run one in a new thread
> c2s.start();
> // Run the other in this thread
> s2c.run();
>
>
> boolean done = false;
> while(!done) {
> try {
> c2s.join();
> done = true;
> } catch (InterruptedException e) {
> // Shouldn't happen. Thread has no wait() or sleep() calls.
> System.out.println(e.getMessage());
> }
> }
> }
>
> ... and StreamForwarder itself:
>
> public class StreamForwarder implements Runnable {
>
> private InputStream input;
> private OutputStream output;
>
> public static final int BLOCKSIZE = 1024;
>
> /**
> * Constructor
> * @param input Something to read from
> * @param output Something to write to
> */
> public StreamForwarder(InputStream input, OutputStream output) {
> this.input = input;
> this.output = output;
> }
>
> /**
> * Run method - read a KB, write a KB, until either an IOException is thrown
> * or we reach EOF.
> */
> public void run() {
> byte[] block = new byte[BLOCKSIZE];
> boolean done = false;
> while(!done) {
> try {
> int size = input.read(block);
> if(size >0) {
> output.write(block,0,size);
> }
> if(size == -1) {
> done = true;
> }
> } catch (IOException e) {
> System.err.println(e.getMessage());
> done = true;
> }
> Thread.yield(); // polite, but surely redundant in this day and age?
> }
> }
> }
>
> --
> "There is no way to peace; peace is the way"
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>


Hotmail: Free, trusted and rich email service. Get it now.
123
Loading...