Can't read more than one message from a socket

C

Chris Birkinshaw

I am connecting to a server and then waiting to receive messages over
the socket. For each message received I wish to then execute some code.

I have tried recv, gets, and readpartial all with no luck.

I tried something like this:

loop {
data = socket.recv( 100 )
puts "Line received"
puts data
}

What I see when sending messages from the server is that the first
message is received and printed, then the program hangs for 15 secs,
then the loop starts but each time the data is empty.

I am obviously doing something really stupid but I've spend hours now on
this so if someone could hint at how to do this I would be most
grateful.

Thanks,

Chris
 
E

Eric Hodel

I am connecting to a server and then waiting to receive messages over
the socket. For each message received I wish to then execute some
code.

I have tried recv, gets, and readpartial all with no luck.

I tried something like this:

loop {
data = socket.recv( 100 )
puts "Line received"
puts data
}

What I see when sending messages from the server is that the first
message is received and printed, then the program hangs for 15 secs,
then the loop starts but each time the data is empty.

I am obviously doing something really stupid but I've spend hours
now on
this so if someone could hint at how to do this I would be most
grateful.

Since you didn't post your entire program, we can only be of limited
assistance.

This program works for me:

$ ruby -rsocket -e 'sv = TCPServer.new nil, 4000; so = sv.accept;
while data = so.read(10) do p :read => data end'
{:read=>"0123456789"}
{:read=>"\r\n234567\r\n"}
$

It has many flaws, for example it doesn't handle any error conditions,
and only responds to one connection from the server.

The output you see is from connecting with telnet:

$ telnet localhost 4000
Trying ::1...
Connected to localhost.
Escape character is '^]'.
0123456789
234567
^]
telnet> quit
Connection closed.
$
 
C

Chris Birkinshaw

Eric said:
$ ruby -rsocket -e 'sv = TCPServer.new nil, 4000; so = sv.accept;
while data = so.read(10) do p :read => data end'
{:read=>"0123456789"}
{:read=>"\r\n234567\r\n"}
$


Thanks for the help. I used your structure (while data = socket.read) as
follows in my client app (after opening the in_socket to the server):

messageCount = 0
while data = in_socket.recv( 100 )
if data.size > 0
messageCount += 1
puts "Received message #{messageCount}: #{data}"
else
puts "empty"
end
end

I put in the check for empty messages because I am seeing some odd
behaviour.
Basically I can send a certain message to this client no problems
(message 1 to 4 below), but as soon as message 5 is received the program
hangs for 15 secs then goes into a mad loop of empty messages:


Received message 1: MESSAGET 18
1234 162 999 9999
Received message 2: MESSAGET 18
1234 162 999 9999
Received message 3: MESSAGET 18
1234 162 999 9999
Received message 4: MESSAGET 18
1234 162 999 9999
Received message 5: MESSAGET 35
0 162 9 0 "&" 82 -1000 2 9 25 "0"
empty
empty
empty
...


Something in that particular received message is making it go bonkers.
Any ideas?
 
R

Roger Pack

I tried something like this:
loop {
data = socket.recv( 100 )
puts "Line received"
puts data
}

recv should work--if you receive "" it means teh connection closed.
Cheers!
-=r
 
B

Brian Candler

Chris said:
while data = in_socket.recv( 100 )

Try using read(100) instead of recv(100).

read returns nil after the socket has been closed.

recv is a very low-level function, and I'd suggest using it only for UDP
datagrams.
 
R

Robert Klemme

2009/1/21 Chris Birkinshaw said:
I am connecting to a server and then waiting to receive messages over
the socket. For each message received I wish to then execute some code.

I have tried recv, gets, and readpartial all with no luck.

I tried something like this:

loop {
data = socket.recv( 100 )
puts "Line received"
puts data
}

What I see when sending messages from the server is that the first
message is received and printed, then the program hangs for 15 secs,
then the loop starts but each time the data is empty.

I am obviously doing something really stupid but I've spend hours now on
this so if someone could hint at how to do this I would be most
grateful.

Are both processes Ruby processes? In that case it's certainly a lot
more hassle free to use DRb. If not, you should define a protocol
yourself. Either use messages with a fixed length or transmit the
length as first item or use a special EOM marker (you could use a line
delimiter for this, which has the advantage that you can use gets or
each without arguments).

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top