Client/server with threads

A

andreas.alin

Yow!
I'm trying to make a script that will act as a server (server 1), and
when a connection to the server server 1 is made, it will start a
thread that will connect to another server (server 2), and it will keep
the connection to server 2, even if the client disconnects.

The thing is that, as I've tried, my client/server will not connect to
another server, and if it does, the client can not disconnect.

Any ideas?

Thanks,
Andreas

----------------------

require 'socket'

class Session < Thread
def initalize(session_id)
super
@session_id = session_id
end

def session_id
@session_id
end

def send_message( message
# This method should send a message to
# server 2
puts message
end
end

threads = []

server = TCPServer.new("0.0.0.0", 12121)

while (session = server.accept)
session_id, message = session.gets.split(";", 2)

t = threads.map {|t| t if t["session_id"] == session_id }.delete_if
{|s| s == nil}.first
puts t
if t
puts "Found thread with existing session_id: #{ session_id }"
t.send :send_message, message
else
threads << Session.new(session) do |t|
Thread.current["session_id"] = session_id
puts "Creating thread for #{ session_id }"
end
end
session.close
end
 
F

Francis Cianfrocca

Yow!
I'm trying to make a script that will act as a server (server 1), and
when a connection to the server server 1 is made, it will start a
thread that will connect to another server (server 2), and it will keep
the connection to server 2, even if the client disconnects.

The thing is that, as I've tried, my client/server will not connect to
another server, and if it does, the client can not disconnect.

Any ideas?

Thanks,
Andreas

----------------------

require 'socket'

class Session < Thread
def initalize(session_id)
super
@session_id = session_id
end

def session_id
@session_id
end

def send_message( message
# This method should send a message to
# server 2
puts message
end
end

threads = []

server = TCPServer.new("0.0.0.0", 12121)

while (session = server.accept)
session_id, message = session.gets.split(";", 2)

t = threads.map {|t| t if t["session_id"] == session_id }.delete_if
{|s| s == nil}.first
puts t
if t
puts "Found thread with existing session_id: #{ session_id }"
t.send :send_message, message
else
threads << Session.new(session) do |t|
Thread.current["session_id"] = session_id
puts "Creating thread for #{ session_id }"
end
end
session.close
end


First, make sure your constructor is getting called. You spelled it
"initalize" instead of "initialize"
 
A

andreas.alin

Oh, thanks. :) Didn't see that. :)

But, now, there are some problems. The program gets stuck in the loop
on line 12, which I want the program to do in the background. (and it
shouldn't get stuck) :)

require 'socket'

class Session < Thread
def initialize(session)
super
puts session
@session_id, @nick, @channels = session.split(";", 3)
@host = "wowow"
@channels = @channels.split(",")
@connected = 0
@connection = TCPSocket.new("127.0.0.1", 12122)
until @connection.closed?
print "a"
if @connected == 0
login
@connected = 1
end
raw = @connection.gets
parse( raw.strip ) unless raw.nil?
end
end

def session_id
@session_id
end

def send_message( message )
puts message
end

def irc_join( channel )
irc_raw( "JOIN #{ channel }" )
end

def irc_nick( nick )
irc_raw( "NICK #{ nick }" )
@nick = nick
end

private

def irc_raw( msg )
@connection.send( "#{ msg }\r\n", 0 )
end

def login
irc_raw( "NICK #{ @nick }" )
irc_raw( "USER #{ @nick } #{ @nick } #{ @host } : #{ @nick } " )
end

def parse( line )
input = line.split(" ")
if input[0][0].chr == ":"
case input[1]
when "001"
@channels.each {|c| irc_join(c) }
when "433"
irc_nick( "#{ @nick }_" )
end
end
end

end

threads = []

server = TCPServer.new("0.0.0.0", 12121)

while (session = server.accept)
session_id, message = session.gets.split(";", 2)

t = threads.map {|t| t if t["session_id"] == session_id }.delete_if
{|s| s == nil}.first
puts t
if t
puts "Found thread with existing session_id: #{session_id}"
t.send :send_message, message
else
threads << Session.new("#{session_id};#{message}") do |t|
Thread.current["session_id"] = session_id
puts "Creating thread for #{ session_id }"
end
end
session.close
end


Francis said:
Yow!
I'm trying to make a script that will act as a server (server 1), and
when a connection to the server server 1 is made, it will start a
thread that will connect to another server (server 2), and it will keep
the connection to server 2, even if the client disconnects.

The thing is that, as I've tried, my client/server will not connect to
another server, and if it does, the client can not disconnect.

Any ideas?

Thanks,
Andreas

----------------------

require 'socket'

class Session < Thread
def initalize(session_id)
super
@session_id = session_id
end

def session_id
@session_id
end

def send_message( message
# This method should send a message to
# server 2
puts message
end
end

threads = []

server = TCPServer.new("0.0.0.0", 12121)

while (session = server.accept)
session_id, message = session.gets.split(";", 2)

t = threads.map {|t| t if t["session_id"] == session_id }.delete_if
{|s| s == nil}.first
puts t
if t
puts "Found thread with existing session_id: #{ session_id }"
t.send :send_message, message
else
threads << Session.new(session) do |t|
Thread.current["session_id"] = session_id
puts "Creating thread for #{ session_id }"
end
end
session.close
end


First, make sure your constructor is getting called. You spelled it
"initalize" instead of "initialize"
 
F

Francis Cianfrocca

unknown said:
Oh, thanks. :) Didn't see that. :)

But, now, there are some problems. The program gets stuck in the loop
on line 12, which I want the program to do in the background. (and it
shouldn't get stuck) :)

Please forgive me, I don't intend to be rude, but this program is not
well thought out. You should reconsider your use of threads in the first
place. Try an implementation with fork until you get it right. (And fork
after you accept, not after you block on a gets from the accepted
socket.)

I think your program gets "stuck" because you're executing your loop in
a subclassed constructor. The new thread of control that you think
you're getting never actually starts running. To prove it, put a print
statement immediately after the accept, and then connect to your program
twice, from two different shells. I predict the second client will
appear to connect (because the TCP server picks it up in the kernel) but
your accept call will not execute more than once.
 
A

andreas.alin

Francis said:
Please forgive me, I don't intend to be rude, but this program is not
well thought out. You should reconsider your use of threads in the first
place. Try an implementation with fork until you get it right. (And fork
after you accept, not after you block on a gets from the accepted
socket.)

I think your program gets "stuck" because you're executing your loop in
a subclassed constructor. The new thread of control that you think
you're getting never actually starts running. To prove it, put a print
statement immediately after the accept, and then connect to your program
twice, from two different shells. I predict the second client will
appear to connect (because the TCP server picks it up in the kernel) but
your accept call will not execute more than once.

Thanks for the advice, and for explaining :)
I'll take a look at fork and see if I can get this working :)
 

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

Similar Threads


Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top