Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TCL multiple sockets communication

40 views
Skip to first unread message

bogdan

unread,
Mar 26, 2006, 7:11:12 AM3/26/06
to
hey!

can anybody tell me if it is possible (in tcl) for a server to open
two(or more) sockets and to talk simultaneousley with two clients on
these two sockets?...and if yes...do you know any links with such
examples?

i tried to do it like this but it dosen't work simultaneousley...

server:

#!/usr/bin/tclsh8.4

proc ServerAlloc {channel1 clientaddr clientport} {

fconfigure $channel1 -buffering line -blocking off

#read from client
puts "Accepted connection from $clientaddr port $clientport channel
$channel1
for Alloc"
gets $channel1 line
puts "Client (alloc) sais: \"$line\""

after 2000
#send message to client
puts $channel1 "mesaj1"
flush $channel1
puts "Sent \"mesaj 1\" to client (alloc)"


after 2000
#send message to client
puts $channel1 "mesaj2"
flush $channel1
puts "Sent \"mesaj 2\" to client (alloc)"

after 3000
#close channel
close $channel1
puts "Channel closed"
}

proc ServerFree {channel2 clientaddr clientport} {

fconfigure $channel2 -buffering line -blocking off
#read from client
puts "Accepted connection from $clientaddr port $clientport channel
$channel2
for Free"
gets $channel2 line
puts "Client (free) sais: \"$line\""

after 2000
#send message to client
puts $channel2 "mesaj1"
flush $channel2
puts "Sent \"mesaj 1\" to client (free)"

after 2000
#send message to client
puts $channel2 "mesaj2"
flush $channel2
puts "Sent \"mesaj 2\" to client (free)"

after 3000
#close channel
close $channel2
puts "Channel closed"
}

socket -server ServerAlloc 2500
socket -server ServerFree 7272

vwait forever


client1:

#!/usr/bin/tclsh8.4

set server localhost
puts "server: $server"

set sockChan [socket $server 2500]
fconfigure $sockChan -buffering line

#recieve from server
gets $sockChan line
puts "Client2: Server sais \"$line\""

#send to server
puts $sockChan "I am client2"
flush $sockChan
puts "Sent \"I am client2\" to server"


gets $sockChan line
puts "Client2: Server sais \"$line\""
#close $sockChan


client 2:

#!/usr/bin/tclsh8.4

set server localhost
puts "server: $server"

set sockChan [socket $server 7272]
fconfigure $sockChan -buffering line

#recieve from server
puts $sockChan "I am client3"
flush $sockChan
puts "Sent \"I am client2\" to server"

#recieve from server
gets $sockChan line
puts "Client3: Server sais \"$line\""

gets $sockChan line
puts "Client3: Server sais \"$line\""
#close $sockChan

sleb...@gmail.com

unread,
Mar 26, 2006, 11:04:34 AM3/26/06
to
bogdan wrote:
> hey!
>
> can anybody tell me if it is possible (in tcl) for a server to open
> two(or more) sockets and to talk simultaneousley with two clients on
> these two sockets?...and if yes...do you know any links with such
> examples?
>
> i tried to do it like this but it dosen't work simultaneousley...
>
> server:
>
> #!/usr/bin/tclsh8.4
> <snipped non-concurrent code>

Use fileevents my friend.

Here's an example how to:

Server code:

#! /usr/bin/env tclsh
proc server {channel} {
set err [catch {set dataLength [gets $channel data]} errmsg]
if {$err != 0} {
puts "Error <$channel>: $errmsg"
puts "Closing connection $channel"
close $channel
} else {
if {$dataLength != -1} {

# Process incoming messages here:
puts "Client $channel sent $data"
puts $channel "Thank you for sending \"$data\""
flush $channel

}
if {[eof $channel]} {
puts "Connection $channel closed"
close $channel
}
}
}

proc accept {channel client port} {
puts "Accepted connection $channel from $client"
fconfigure $channel -translation auto -blocking 0
fileevent $channel readable "server $channel"
}

socket -server accept 1234
vwait forever


Test client code:

#! /usr/bin/env tclsh
proc client {channel} {
set err [catch {set dataLength [gets $channel data]} errmsg]
if {$err != 0} {
puts "Error <$channel>: $errmsg"
puts "Closing connection $channel"
close $channel
} else {
if {$dataLength != -1} {

# Process incoming messages here:
puts "Server sent $data"

}
if {[eof $channel]} {
puts "Connection $channel closed"
close $channel
}
}
}

set connection1 [socket localhost 1234]
fconfigure $connection1 -translation auto -blocking 0
fileevent $connection1 readable "client $channel"
set connection2 [socket localhost 1234]
fconfigure $connection2 -translation auto -blocking 0
fileevent $connection2 readable "client $channel"

puts $connection1 "This message is from connection1"
flush $connection1

puts $connection2 "This message is from connection2"
flush $connection2

puts $connection1 "Second message from connection1"
flush $connection1

puts $connection2 "Second message from connection2"
flush $connection2

after 2000 "close $connection2"
after 2000 "close $connection1"
vwait forever


In the example above the server only opens a single port. You can
easily modify it to accept multiple ports by adding another [socket
-server accept $portnumber].

Ulrich Schöbel

unread,
Mar 26, 2006, 11:47:16 AM3/26/06
to
Am Sun, 26 Mar 2006 08:04:34 -0800 schrieb sleb...@yahoo.com:

> bogdan wrote:
>> hey!
>>
>> can anybody tell me if it is possible (in tcl) for a server to open
>> two(or more) sockets and to talk simultaneousley with two clients on
>> these two sockets?...and if yes...do you know any links with such
>> examples?
>>
>> i tried to do it like this but it dosen't work simultaneousley...
>>
>> server:
>>
>> #!/usr/bin/tclsh8.4
>> <snipped non-concurrent code>
>
> Use fileevents my friend.
>
> Here's an example how to:
>
> Server code:
>

... server code elided

>
> proc accept {channel client port} {
> puts "Accepted connection $channel from $client"
> fconfigure $channel -translation auto -blocking 0
> fileevent $channel readable "server $channel"
> }
>
> socket -server accept 1234
> vwait forever
>
>
> Test client code:

... client code elided

> In the example above the server only opens a single port. You can
> easily modify it to accept multiple ports by adding another [socket
> -server accept $portnumber].

Hi Bogdan,

for mor sockets to accept connections just add a server id
to the socket and accept commands:

socket -server {accept Server1} 1234
socket -server {accept Server2} 1235
socket -server {accept Server3} 1236

proc accept {srv channel client port} {
...
}

srv will contain the server id.

Kind regards

Ulrich

sleb...@gmail.com

unread,
Mar 26, 2006, 7:12:33 PM3/26/06
to

Server ID's are only necessary if each port does different things
(which is what the TCP/IP model intended). But from the OPs original
example I had a feeling that he wanted all opened ports to do the same
thing. Kind of like bittorrent opening multiple listening ports but
they are all bittorent anyway. For a single service running on multiple
ports you can simply do:

socket -server accept 1234
socket -server accept 1235
socket -server accept 1236

proc accept {channel client port} {

...
}

Ulrich's example is useful for doing things like:

socket -server {accept http_server} 80
socket -server {accept pop3_server} 110
socket -server {accept custom_server} 1234

proc accept {server channel client port} {
fconfigure $channel -blocking 0
switch -exact $server {
"http_server" {
fileevent $channel readable "httpProc $channel"
}
"pop3_server" {
fileevent $channel readable "pop3Proc $channel"
}
"custom_server" {
fileevent $channel readable "myServerProc $channel"
}
}
}

bogdan

unread,
Mar 27, 2006, 3:44:58 AM3/27/06
to
thanks for the help you guys:)

Donal K. Fellows

unread,
Mar 27, 2006, 7:37:30 AM3/27/06
to
sleb...@yahoo.com wrote:
> Ulrich's example is useful for doing things like:
>
> socket -server {accept http_server} 80
> socket -server {accept pop3_server} 110
> socket -server {accept custom_server} 1234
>
> proc accept {server channel client port} {
> fconfigure $channel -blocking 0
> switch -exact $server {
> "http_server" {
> fileevent $channel readable "httpProc $channel"
> }
> "pop3_server" {
> fileevent $channel readable "pop3Proc $channel"
> }
> "custom_server" {
> fileevent $channel readable "myServerProc $channel"
> }
> }
> }

I'd do this instead:

package require log ;# from tcllib
socket -server {accept httpProc} 80
socket -server {accept pop3Proc} 110
socket -server {accept myServerProc} 1234


proc accept {server channel client port} {
fconfigure $channel -blocking 0

log::logMsg "Connection from ${client}:${port}\
to $channel (service = $server)"
fileevent $channel readable "$server $channel"
}

It's both more flexible and shorter. And keeps a record of who is
connecting to you, which can be very helpful indeed.

Donal.

bogdan

unread,
Mar 27, 2006, 10:08:50 AM3/27/06
to
thanks fot the post...i already resolved the problem...one server will
do for what i need... still this is goot info to remember for the
future :)

0 new messages