socket - Open a TCP network connection socket ?options? host port socket -server command ?options? port This command opens a network socket and returns a channel identifier that may be used in future invocations of commands like read, puts and flush. At present only the [TCP] network protocol is supported; future releases may include support for additional protocols like [UDP] and [IPX]. The socket command may be used to open either the client or server side of a connection, depending on whether the -server switch is specified. See also the official documentation at http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/socket.htm Server sockets can only accept incoming connections when Tcl has an event loop running. All sockets use the system encoding by default; this is probably not what you want, but it is up to the protocol to define or negotiate something more suitable. ---- '''Service details''' Port numbers are integers but depending upon your system configuration you may be able to use symbolic names for some services. The calls the getservbyname sockets API function which uses a services database file to convert between port numbers and service names. ''This function is quite limited on certain platforms (eg:Windows)''. [slebetman]: this is partially untrue (see comment below). Some lists of protocols and their associated port numbers are: * Official [IANA] list [http://www.iana.org/assignments/port-numbers] (0.5+ MB text file). * http://www.akerman.ca/port-table.html * Network Sorcery list [http://www.networksorcery.com/enp/protocol/ip/ports00000.htm]. On unix-type systems you very likely have an /etc/services file which is used by this function. ''It typically has the same syntax as the official IANA list referenced above'' [slebetman]: this is also not true, similar syntax but not the same. The ''typical'' /etc/services file has the syntax: # comment service_name port_number/protocol alias where comments can appear at the end of line and aliases can be used instead of the service_name when requesting for the port number (for example both "smtp" and "mail" refer to port 25). The IANA list on the other hand has the syntax: service_name port_number/protocol description/comment # person who requested the port for the service OR relevant documentation In addition, for the IANA list, all text above the lines: Port Assignments: Keyword Decimal Description References ------- ------- ----------- ---------- are to be considered as comments. [slebetman]:On Windows, starting from Windows 2000 you have a C:\WINNT\SYSTEM32\DRIVERS\ETC\SERVICES or C:\WINDOWS\SYSTEM32\DRIVERS\ETC\SERVICES file serving the exact same function as the Unix counterpart and has exactly the same syntax. The currently shipping ''services'' file for Windows XP is dated 1999 so it doesn't have newer registered ports such as '''tcpmux''' and '''rje'''. Nonetheless this file is editable and can be easily updated by downloading the current 2006 IANA definitions from the net. ---- How to use the -async option? Pasted from the Tcl'ers chat dgp proc verify s { set msg [fconfigure $s -error] if {$msg ne ""} { # an error connecting } # set up to use $s } set s [socket -async $host $port] fileevent $s writable [list verify $s] dgp over the Tcl versions and platforms, I've found it helpful to test dgp [puts -nonewline $s ""] and [fconfigure $s -peername] to be *really* sure you have a successful socket connection. ---- [Cameron Laird] wrote in [the comp.lang.tcl newsgroup]: The most widely-used solution ''(for ensuring only a single instance of an app is running on one machine)'', I think, is to set up a do-nothing networking service. Have your application socket -server ... 5678 when it first starts. If it's unable to do so because another service is already on 5678, take that as a previous instance of the application. Otherwise, continue. For an implementation, see [How do I manage lock files in a cross platform manner in Tcl] Notice this approach is reasonably portable. CL himself notes, somewhat later, that this is a bit "tricky", and not on the main stream of socket use; it's really socket's contribution to the theme of [singleton application]s. ---- Sockets are also one way on [How can Tcl programs on two different machines communicate]. [JH] writes on sockets in http://aspn.activestate.com/ASPN/Cookbook/Tcl/Recipe/65436 . More possibilities are listed in the [Inventory of IPC methods]. Yet another example of socket service appears in http://moogy.unstable.org:8080/simple.sockets.tar.gz . http://www.tcl.tk/scripting/netserver.html is an excellent tutorial showing how to write both server and client sides of an echo service. ---- One little-known corner of TCP/IP is "[port 0 networking]". ---- Several challenges in effective network programming have to do with [DNS] pragmatics. [DKF] wrote, "numeric addresses are never resolved on socket creation on Unix, but they *are* on Windows (but I do not know if it is *really* doing it, as that depends on the Winsock implementation)." ---- One question that seems to arise often is about [how to send a file through a socket connection]. ---- As of 8.5, there's apparently no clean socket [introspection]. Socket handles '''do''' show up in "[file] channels sock*", though, so, as long as one is willing to rely on this slightly dirty match, the answer is computable. [DGP] See Tcl Feature Request 455867 [http://sourceforge.net/tracker/index.php?func=detail&aid=455867&group_id=10894&atid=360894]. ---- [GPS]: from the [Tcl Chatroom]: * [xmav000] i'm trying to implement a game client/server architecture. can anyone give me some hints which projects i could look at to get some more ideas. there probably are some chat client/server (which will have to be a part of course) * [GPS] xmav: I have some code for you. Server tclsh: % proc accept {s addr port} {puts $s "Hi and bye!"; close $s} % socket -server accept 8888 Client tclsh: % set s [socket localhost 8888] sock3 % gets $s Now the client will block, because the server isn't running its event loop. So go to the server tclsh and type: update and you will see in the client: Hi and bye! (Wikified soon) * [GPS] I'm not sure if that's enough of what you need. Everything for a game server should be built upon this foundation though. * [GPS] fileevent is the command you will use to process sockets when they are readable or writable. * [suchenwi] GPS: hey, that looks cool! PLEASE wikify it (plus discussion)! [GPS]: I would like to clarify a bit. [fileevent] interacts with the event loop allowing us to do other things (rather than just blocking) and have an event callback invoked when data is ready to be send/received on a [socket] channel. ---- [[ ... [ceptcl] ...]] ---- [kostix] '''Issues with unexpected remote disconnects and buffered blocking sockets''' I've faced a problem while working with ''blocking'' sockets on the client side: in my case the remote server could intentionally interrupt the connection. It was a simple command/response prototol, so it was native for a client to use '''puts''' and '''gets''' on blocking socket to sent/receive ASCII stanzas. The problem looked like this: when I send a command to the server using '''puts''', it works OK ''even if the connection was reset by the server.'' The same thing applies to '''flush''': it completes successfully even if the output buffer has data but there's no TCP connection already. That's all due to the buffering that is '''on''' for sockets by default. There are some ways to know whether the connection was reset by the peer: * do '''gets''' that will return -1 and set EOF status on the channel so that calls to '''eof''' will return true. This is bad in that respect that if we send commands to a server and ''then'' reads responses, such "preventive" '''gets''' will block forever. * fill up the buffer. This depends on what type of buffering is set. By default, socket is in '''full''' buffering mode which means it may buffer up to 4k chars (by default). In '''line''' buffering mode it will buffer one line. Unfortunately, in either case the first '''puts''' will not fail. In the line buffering mode the second call to '''puts''' will fail, in the full buffering mode you should call '''puts''' untill the buffer is full. This solution is bad when your protocol is line-oriented since you must output data by lines and wait for ACK for that lines. * ''switch off buffering of the socket'' (with '''fconfigure $chan -buffering none'''). This actually solves the problem since the very first call to '''puts''' will fail if the connection was reset by the peer behind your back. So you only have to wrap the call to '''puts''' with the '''catch''' clause. Some people on [Tcl Chatroom] advised to switch to async (non-blocking ) sockets or use [expect] but I think such simple line-based ASCII protocols can be implemented in pure Tcl and w/o complexities of non-blocking sockets. Just keep this buffering issue in mind. ---- [Tcl syntax help] - [Arts and crafts of Tcl-Tk programming] - [Category Command] - [Category Networking]