TCL有关Server Client的更多信息

时间:2014-09-18 14:54:38

标签: tcl

我对TCL很新,并且一直在尝试服务器/客户端示例。我想进一步扩展这一点,以便服务器可以将数据发送到客户端(如果在" Echo"过程中插入,我会管理的数据:请参阅我使用的示例代码)。我想做的是,例如,"主要功能",调用一个程序,将数据发送到客户端,而不必在" Echo"过程

# -------------------------------------------------------
# PROCEDURE Echo_server
# -------------------------------------------------------

proc Echo_server {port} {
    global echo
    global i
    set i 0
    set echo(main) [socket -server Echo_accept $port]
    vwait forever
}

# -------------------------------------------------------
# PROCEDURE Echo_accept
# -------------------------------------------------------

proc Echo_accept {sock addr port} {
    global echo
    puts "Accept $sock from $addr port $port, $echo(main)"
    set echo(addr,$sock) [list $addr $port]
    fconfigure $sock -buffering line
    fileevent $sock readable [list Echo $sock]
}

# -------------------------------------------------------
# SEND AND RECIEVE DATA.
# -------------------------------------------------------

proc Echo {sock} {
    global echo
    if {[eof $sock] || [catch {gets $sock line}]} {
        # end of file or abnormal connection drop
        close $sock
        puts "Client at $echo(addr,$sock) has disconnected."
        unset echo(addr,$sock)
    } else {
        if {[string compare $line "stop_new_conections"] == 0} {
            # Prevent new connections.
            # Existing connections stay open.
            puts $sock "Closing all other connections"
            puts "Client at $echo(addr,$sock) closed all incoming connections"
            close $echo(main)
        }
        puts "Client: \"$line\""
        set out [gets stdin]
        puts $sock $out
    }
}

# -------------------------------------------------------
# MAIN FUNCTION
# -------------------------------------------------------
Echo_server 5555
# here is where I would like to call a send proc that would send data to the client.

2 个答案:

答案 0 :(得分:2)

在客户端连接并且在accept处理程序中处理之前,您不能发送任何内容。一旦接受客户端连接,就可以使用套接字的可写事件(fileevent $sock writable ...),一旦套接字变为可写,您的处理程序就可以向新连接的客户端写入内容。

将数据发送到连接的客户端后,应使用fileevent $channel writable {}删除可写的文件事件。您还应该使用fconfigure $channel -error检查可写事件处理程序中的连接错误。 picoirc.tcl代码在Write过程中有一些示例,wiki

上有其他代码

您也可以在accept函数中写入新连接(即:将$ sock“hello”)放入Echo_accept函数中,但通常最好在Tcl服务器中使用async io,因为它确实非常好简单而有效。

答案 1 :(得分:0)

非常感谢您的快速反应。我没有期望得到答案,所以我很高兴看到这个"论坛"确实有效! 我设法通过对服务器执行以下操作来解决它。客户几乎是一回事。它运行正常,但是我使用了全局变量(我刚刚读过它们并不过于推荐)但是它的功能却很有用!

set service_port  5555

proc accept_client_connection {channel_name address port} {
    global client_address
    global client_channel
    global client_port
    global connection
    fconfigure $channel_name -buffering none
    set client_channel $channel_name
    set client_address $address
    set client_port $port
    set connection 1
}

proc close_client_connection {} {
    global client_address
    close $client_address
}

proc Recieve_Data {} {
    global client_channel
    gets $client_channel msg
    # Confirm reception
    puts $client_channel "OK"
    return $msg
}

proc Send_Data {data} {
    global client_channel
    puts $client_channel $data
    gets $client_channel answer
    if { $answer != "OK" } {
        return false
    }
    return true
}

set server_sock [socket -server accept_client_connection $service_port]
vwait connection
puts "Connection established with client $client_channel with address: $client_address:$client_port\n"
set client_data [Recieve_Data]
puts "Client: \"$client_data\""
set data_to_send "HELLO CLIENT!"
while { ! [ Send_Data $data_to_send ] } {
    puts "Error sending data to server..."
    after 1000
}

vwait forever