File: tcp-echo-client.tcl

package info (click to toggle)
srt 1.5.4-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,804 kB
  • sloc: cpp: 52,175; ansic: 5,746; tcl: 1,183; sh: 318; python: 99; makefile: 38
file content (110 lines) | stat: -rw-r--r-- 2,317 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/tclsh

set read_running 0
set write_running 0
set read_eof 0 
set theend 0

set nread 0
set nwritten 0

proc ReadBack {fd} {

	if { !$::write_running } {
		puts stderr "ERROR: connection closed unexpectedly!"
		set ::theend 1
		return
	}

	set r [read $fd 4096]
	if {$r == ""} {

		if {[eof $fd]} {
			puts stderr "EOF on socket"
			set ::read_running 0
			return
		}

		# --- puts stderr "SPURIOUS, not reading"
		return
	}

	# --- puts stderr "REPRINTING [string bytelength $r] bytes"
	puts -nonewline stdout $r
	incr ::nwritten [string bytelength $r]
	# --- puts stderr "DONE"

	set remain [expr {$::nread - $::nwritten}]
	if { $::read_eof } {
		puts stderr "Finishing... read=$::nread written=$::nwritten diff=[expr {$::nwritten - $::nread}] - [expr {100.0*$remain/$::nread}]%"
	}

	# Nothing more to read
	if {$remain == 0} {
		puts stderr "NOTHING MORE TO BE WRITTEN - exiting"
		set ::theend 1
		return
	}

	after idle "ReadBack $fd"
}

proc SendToSocket {fd} {
	global theend

	if { !$::write_running } {
		# --- puts stderr "SERVER DOWN, not reading"
		fileevent stdin readable {}
		return
	}

	if { $::read_eof } {
		# Don't read, already EOF.

	}
	# --- puts stderr "READING cin"
	set r [read stdin 4096]
	if {$r == ""} {
		if {[eof stdin]} {
			if {!$::read_eof} {
				puts stderr "EOF, setting server off"
				set ::read_eof 1
			}
			# Just enough when the next SendToSocket will
			# not be scheduled.
			return
		}
		# --- puts stderr "SPURIOUS, not reading"
		return
	}

	# --- puts stderr "SENDING [string bytelength $r] bytes"
	# Set blocking for a short moment of sending
	# in order to prevent losing data that must wait
	fconfigure $fd -blocking yes
	puts -nonewline $fd $r
	incr ::nread [string bytelength $r]
	fconfigure $fd -blocking no

    # --- if {[fblocked stdin]} {
    # --- 	# Nothing more to read
    # --- 	return
    # --- }
	after idle "SendToSocket $fd"
}

set fd [socket {*}$argv]
fconfigure $fd -encoding binary -translation binary -blocking no -buffering none
fileevent $fd readable "ReadBack $fd"

fconfigure stdin -encoding binary -translation binary -blocking no
fconfigure stdout -encoding binary -translation binary
fileevent stdin readable "SendToSocket $fd"

# --- puts stderr "READY, sending"
set read_running 1
set write_running 1

vwait theend

close $fd