tcl socket 编程

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值