Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TCL Chat Server

Status
Not open for further replies.

Kalantir

Programmer
Oct 24, 2010
1
US
So, I wrote a basic chat program in TCL as an exercise to help myself get used to the language and I have encountered some major problems that I don't understand.

So, I can start the server, and telnet in to it (port 5000). That all works fine. It supports multiple connections without any apparent errors. However, I have noticed some problems when I attempt to connect via the program Putty.

The first is that windows telnet users lose localecho. The second is that garbage data seems to be getting attached to messages. There appears to be some garbage data before a putty user connects, but not anything like afterwards.

Does anyone have any ideas what is going on?

Here is a log file
It is worth noting that connected users don't see any of this garbage data. Only the server acknowledges it.
Code:
Server: New Connection - sock208
Server: New user - Kalantir
Kalantir: Whats upAnybody here?
Kalantir: Hello...? ...
Server: New Connection - sock220
Server: New user - Hideaki
Hideaki: Whats up Kalantir!
Kalantir: no much... just chillaxin
Server: New Connection - sock224
Server: New user - ÿûÿû ÿûÿû'ÿýÿûÿýputty User
ÿûÿû ÿûÿû'ÿýÿûÿýputty User: ÿþÿþ ÿþÿþ'ÿüI use putty!
Kalantir: ÿþÿþ ÿþÿþ'ÿûÿýÿûÿþÿþ ÿþÿþ'ÿûÿûÿüÿü ÿüÿü'ÿþccool
Hideaki: ÿþÿþ ÿþÿþ'ÿûÿýÿûÿþÿþ ÿþÿþ'ÿûÿûÿüÿü ÿüÿü'ÿþÿüÿü ÿüÿü'ÿýÿûÿüÿü ÿüÿü'ÿþÿþ ÿþÿþ'ÿüI just lost my localecho for no reason
ÿûÿû ÿûÿû'ÿýÿûÿýputty User: ÿþÿþ ÿþÿþ'ÿüÿû$ÿýÿüÿþI 
Server: Connection closed - sock224 "ÿûÿû ÿûÿû'ÿýÿûÿýputty User"

netio.tcl
Code:
# Read data in to $newPacket on file desciptor $fd
proc recv {fd newPacket} {
  upvar $newPacket data
  
  return [gets $fd data]
}

# Send $data to given file descriptor $fd
proc send {fd data} {
  puts -nonewline $fd $data
  flush $fd
}

server.tcl
Code:
# Load in our send and recv functions
source "netio.tcl"

# New connection
proc accept {fd addr port} {
  global users

  # Set nonblocking
  fconfigure $fd -blocking 0

  puts "Server: New Connection - $fd"
  set users($fd.buf) ""

  # Get an alias for our user
  send $fd "What is your name? "
  set users($fd.state) "Name"

  # when data is ready to be read, call our handler
  fileevent $fd readable "handler $fd"
}

# Send a message to every connected user
proc msgAll {msg} {
  global users
  foreach index [array names users "*.name"] {
    send $users($users($index)) "\r\n$msg\r\n> "
  }
}

# Handle connections
proc handler {fd} {
  global users
  global didRead

  incr didRead
  if {[recv $fd users($fd.buf)] < 0} {
    # Connection closed by client
    if {![fblocked $fd]} {
      fileevent $fd readable {}

      # Make sure we don't print this if user didn't have a name
      if {[info exists users($fd.name)]} {
        puts "Server: Connection closed - $fd \"$users($fd.name)\""
        msgAll "$users($fd.name) has left the chat!"
      }

      # Close and delete the user
      close $fd
      array unset users $fd.*
    }

  # Already existing connection
  } else {

    # Check what state the user is in
    switch $users($fd.state) {

      # Pick a name
      "Name" {
        # Set the user's name
        set users($fd.name) $users($fd.buf)
        set users($users($fd.name)) $fd

        # Change the user's state
        set users($fd.state) "Main"

        # Announce the new user
        msgAll "$users($fd.name) has joined the chat!"
        puts "Server: New user - $users($fd.name)"
      }

      # Chat with the other users
      "Main" {
        # Display the buf to everyone
        msgAll "$users($fd.name) - $users($fd.buf)"
        puts "$users($fd.name): $users($fd.buf)"
      }
    }
  }
}

# Global Variables
set users() 0
set didRead 0
set shutdown 0

# Listen on port 5000
set myServer [socket -server accept 5000]
puts "Server: Ready for incoming data..."

while {$shutdown == 0} {
  vwait didRead
  update
}

close $myServer
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top