Tcl_OpenTcpClient(3)

πŸ“¦
version 9.0.3 Β· 2 versions
, in alpine 3.23, alpine 3.24, fedora 43, fedora 44, nixos 26.05

πŸ’– Tcl_OpenTcpClient(3) β€” the Tcl Library Procedures glow-up πŸ’–

okay so bestie. you want channels that talk over TCP sockets? this is the page. it lives in the Tcl Library Procedures section of the Tcl manual, and it's covering four functions: Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer, and Tcl_OpenTcpServerEx. no cap, they're the convenience squad for socket networking. let's get into it 🫢


✨ NAME ✨

Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer, Tcl_OpenTcpServerEx β€” the procedures that open channels using TCP sockets πŸ’…


🌸 SYNOPSIS 🌸

#include <tcl.h>

Tcl_Channel
Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async)

Tcl_Channel
Tcl_MakeTcpClientChannel(sock)

Tcl_Channel
Tcl_OpenTcpServer(interp, port, myaddr, proc, clientData)

Tcl_Channel
Tcl_OpenTcpServerEx(interp, service, myaddr, flags, backlog, proc, clientData)

πŸŽ€ ARGUMENTS πŸŽ€

  • Tcl_Interp *interp (in) β€” the Tcl interpreter we're gonna use for reporting errors. if it's non-NULL and something goes wrong, the error message gets dropped right into the interpreter's result. πŸ’Œ
  • int port (in) β€” a port number. you either connect to it as a client or listen on it as a server.
  • const char *service (in) β€” a string spelling out the port number, for connecting as a client or listening as a server.
  • const char *host (in) β€” a string with a host name or address for the remote end of the connection. πŸ›°οΈ
  • int myport (in) β€” the port number for the client's end of the socket. if it's 0, the port number gets allocated at random. 🎲
  • const char *myaddr (in) β€” a string with the host name or address of the network interface for the local end of the connection. if it's NULL, a default interface gets chosen for you.
  • int async (in) β€” if nonzero, the client socket connects to the server asynchronously. ⏳
  • int backlog (in) β€” length of the OS listen backlog queue. use -1 for the default value.
  • unsigned int flags (in) β€” an ORed combination of TCL_TCPSERVER_* flags that say extra stuff about the socket being created.
  • void *sock (in) β€” platform-specific handle for a client TCP socket.
  • Tcl_TcpAcceptProc *proc (in) β€” pointer to a procedure that gets invoked every single time a new connection is accepted through the socket. πŸ“ž
  • void *clientData (in) β€” an arbitrary one-word value you pass along to proc.

πŸ¦‹ DESCRIPTION πŸ¦‹

these functions are the convenience procedures for making channels that talk over TCP sockets. the operations you can do on a channel are described in the manual entry for Tcl_OpenFileChannel. πŸ’«


🌈 TCL_OPENTCPCLIENT

Tcl_OpenTcpClient opens a client TCP socket connected to a port on a specific host, and hands back a channel you can use to communicate with the server.

the host to connect to can be specified either as a domain name style name (e.g. www.sunlabs.com), or as a string containing the alphanumeric representation of its four-byte address (e.g. 127.0.0.1). use the string localhost to connect to a TCP socket on the host where the function is invoked. 🏠

the myaddr and myport arguments let a client specify an address for the local end of the connection. if myaddr is NULL, then an interface is chosen automatically by the operating system. if myport is 0, then a port number is chosen at random by the operating system. 🎰

if async is zero, the call to Tcl_OpenTcpClient returns only after the client socket has either successfully connected to the server, or the attempted connection has failed. if async is nonzero, the socket is connected asynchronously and the returned channel may not yet be connected to the server when the call to Tcl_OpenTcpClient returns.

okay so here's the vibe for that async case, listen close πŸ‘‡

  • if the channel is in blocking mode and an input or output operation is done on the channel before the connection is completed or fails, that operation will wait until the connection either completes successfully or fails.
  • if the channel is in nonblocking mode, the input or output operation will return immediately, and a subsequent call to Tcl_InputBlocked on the channel will return nonzero.

the returned channel is opened for reading and writing. πŸ“–βœοΈ if an error occurs in opening the socket, Tcl_OpenTcpClient returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. plus, if interp is non-NULL, an error message is left in the interpreter's result.

🚨 heads up bestie: the newly created channel is not registered in the supplied interpreter. to register it, use Tcl_RegisterChannel. and if one of the standard channels β€” stdin, stdout or stderr β€” was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. ikyk 😌

πŸ’œ TCL_MAKETCPCLIENTCHANNEL

Tcl_MakeTcpClientChannel creates a Tcl_Channel around an existing, platform specific, handle for a client TCP socket. it's giving "i already have the socket, just wrap it for me" ✨

🚨 same energy: the newly created channel is not registered in the supplied interpreter. to register it, use Tcl_RegisterChannel. and if one of the standard channels β€” stdin, stdout or stderr β€” was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel.

πŸ”₯ TCL_OPENTCPSERVER

Tcl_OpenTcpServer opens a TCP socket on the local host on a specified port, and uses the Tcl event mechanism to accept requests from clients that want to connect to it. the myaddr argument specifies the network interface. if myaddr is NULL the special address INADDR_ANY should be used to allow connections from any network interface. 🌍

every time a client connects to this socket, Tcl creates a channel for the new connection and invokes proc with information about the channel. proc must match this prototype:

typedef void Tcl_TcpAcceptProc(
        void *clientData,
        Tcl_Channel channel,
        char *hostName,
        int port);

breaking down the args it gets handed:

  • clientData β€” will be the same as the clientData argument to Tcl_OpenTcpServer
  • channel β€” the handle for the new channel
  • hostName β€” points to a string containing the name of the client host making the connection
  • port β€” contains the client's port number

the new channel is opened for both input and output. if proc raises an error, the connection is closed automatically. proc has no return value, but if it wishes to reject the connection it can close channel. πŸ™…β™€οΈ

Tcl_OpenTcpServer normally returns a pointer to a channel representing the server socket. if an error occurs, Tcl_OpenTcpServer returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. in addition, if the interpreter is non-NULL, an error message is left in the interpreter's result.

the channel returned by Tcl_OpenTcpServer cannot be used for either input or output. it is simply a handle for the socket used to accept connections. the caller can close the channel to shut down the server and disallow further connections from new clients. πŸšͺ

πŸ’€ critical vibe check: TCP server channels operate correctly only in applications that dispatch events through Tcl_DoOneEvent or through Tcl commands such as vwait. otherwise Tcl will never notice that a connection request from a remote client is pending. not me forgetting the event loop… 😭
🚨 and again: the newly created channel is not registered in the supplied interpreter. to register it, use Tcl_RegisterChannel. and if one of the standard channels β€” stdin, stdout or stderr β€” was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel.

🧚 TCL_OPENTCPSERVEREX

Tcl_OpenTcpServerEx behaviour is identical to Tcl_OpenTcpServer but gives more flexibility to the user by providing a mean to further customize some aspects of the socket via the flags parameter. πŸ‘‘

available flags (dependent on platform) are:

  • TCL_TCPSERVER_REUSEADDR
  • TCL_TCPSERVER_REUSEPORT

🌈 PLATFORM ISSUES 🌈

  • on Unix platforms, the socket handle is a Unix file descriptor as returned by the socket system call.
  • on the Windows platform, the socket handle is a SOCKET as defined in the WinSock API. πŸͺŸ

πŸ‘‘ SEE ALSO πŸ‘‘

Tcl_OpenFileChannel(3), Tcl_RegisterChannel(3), vwait(n)


⭐ KEYWORDS ⭐

channel, client, server, socket, TCP


and that's the whole page bestie, you ate it πŸ’… this was Tcl_OpenTcpClient(3) from the Tcl manual, version 9.0 β€” mwah, go build something iconic with it πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from