tcl编程很简单,但tcl只支持tcp协议,可以通过tcl编写客户端和服务器端
编写服务器端很简单,譬如 socket -server callback 9999;#此处callback是一个事先写好的回调函数,需要接受三个参数socketid remote address和 remote port 如果该pc有多个网卡,缺省针对所有接口,可以通过选项 myaddr 指定特定ip socket -myaddr 1.1.1.1 -server callback 9999 当远端客户端请求该端口时,这个回调函数就会被调用,另外作为服务器端的服务必须进入tcl事件循环,可通过vwait实现,可以通过fconfigure 或者 chan配置socket的I/O属性,可以设定blocking 和 buffering等多个选项 blocking可以为1 (缺省值 表示阻塞模式 就是read gets puts在没有东东可读可写时,阻塞程序继续进行) blocking可以为0 (表示非阻塞模式 该模式必须跟事件同时使用,应用该模式read gets puts在没有东东可读可写时,立即返回不再等待) buffering可以为full (缺省值 tcl将 输出的字符串进行缓冲 直到内部buffer满或者调用flush) buffering可以为line (有换行符时 tcl自动flush) buffering可以为none (每次输出操作后 tcl自动flush) 另外在callback中需要使用fileevent给socket设定可读或者可写时的回调函数。 可读可以理解为接受缓存中有数据了,当socket连接完成或者失败时,socket状态变为可读状态 fileevent $socketid readable [list readcallback $socketid] fileevent $socketid writable [list writecallback $socketid] socket -server callback 9999; proc callback {socketid addr port} { fconfigure $socketid -blocking 0 -buffering line;#非阻塞模式 按行flush fileevent $socketid readable [list readcallback $socketid]; } proc readcallback {socketid} { if {[eof $ socketid ] || [catch {gets $ socketid line} err]} { close $ socketid ; } else { #deal with line; suppose line is tcl scripts eval it and return the results puts line=$line if {[catch {eval $line} err]} { puts $ socketid $err } else { puts $ socketid $err } } } vwait forever 如果运行了上面代码,我们可以再写一个socket客户端的代码 socket localhost 9999;#如果有多个ip地址可以用-myaddr选择ip,也可以用-myport选择端口,否则由系统指定一个端口,-myaddr addr ,使用-async可以使socket工作在异步模式,当需要puts数据时再建立 上面命令返回一个socket id,可以通过该id对socket进行操作 set socketid [socket localhost 9999]; puts $socketid "hello"; flush $socketid;#如果前面使用fconfigure 配置缓冲为line即可不用flush fconfigure $socketid -buffering line gets $socketid value 28 % set value invalid command name "hello" 所以 对于socket编程 必须首先设计双方通信的消息和处理方法 如下我们给上面代码增加两个proc print 和 compute ,当客户端根据事先约定输入时 服务器就能给出相应的输出了 proc print {msg} { return [clock format [clock seconds]]/t$msg } proc compute {args} { return "expr/($args)=[expr $args]" } fileevent $socketid readable [list readcallback $socketid] fileevent $socketid writable [list writecallback $socketid] socket -server callback 9999; proc callback {socketid addr port} { fconfigure $socketid -blocking 0 -buffering line;#非阻塞模式 按行flush fileevent $socketid readable [list readcallback $socketid]; } proc readcallback {socketid} { if {[eof $socketid] || [catch {gets $socketid line} err]} { close $socketid; } else { #deal with line; suppose line is tcl scripts eval it and return the results puts line=$line if {[catch {eval $line} err]} { puts $socketid $err } else { puts $socketid $err } } } vwait forever 在客户端运行 set socketid [socket localhost 9999]; fconfigure $socketid -buffering line puts $socketid "hello"; gets $socketid msg % set msg invalid command name "hello" puts $socketid "print hello" gets $socketid msg % set msg Fri Sep 03 11:28:47 +0800 2010 hello puts $socketid "compute 1+1" gets $socketid msg % set msg expr(1+1)=2 |
tcl socket 编程
最新推荐文章于 2023-03-19 06:38:58 发布