--****************************************************************************** --* * --* File: TkSocket_02.lua Revision: 1.0 * --* * --* Contents: experiments with TCP sockets under TkLua * --* * --* Creation: 11.03.2002 Last Modification: 11.03.2002 * --* * --* Platform: IBM-compatible PC running Windows 98SE * --* * --* Environment: Lua 4.0, TkLua 4.0 * --* * --* Author: Andreas Rozek Phone: ++49 (711) 6770682 * --* Kirschblütenweg 15 Fax: - * --* D-70569 Stuttgart EMail: Andreas.Rozek@T-Online.De * --* Germany * --* * --* URL: http://www.Andreas-Rozek.de/ * --* * --* Copyright: the software is published under the "GNU Lesser General Pub- * --* lic License" (see "http://www.fsf.org/copyleft/lesser.html" * --* for additional information) * --* * --* Comments: this is the first experiment with LuaSockets under TkLua 4.0 * --* * --****************************************************************************** dofile("Lua_02_Lib.lua"); -- provides an extended 'tostring' function etc. dofile("TkLua_00_Lib.lua"); -- provides a simple Tk Console local Icon = "./Lua.gif";-- specifying the file name is already sufficient local Title = "TkSocket_02"; local Subtitle = "experiments with TCP sockets under TkLua"; local Status = "(no special action required)"; --****************************************************************************** --* * --* main program * --* * --****************************************************************************** local CircleOffIcon = "./Circle_Off.gif"; local CircleOnIcon = "./Circle_On.gif"; local CircleOkIcon = "./Circle_Ok.gif"; local CircleCancelIcon = "./Circle_Cancel.gif"; local TextFont = "-*-helvetica-bold-r-*--12"; -- just an abbreviation --**** define window components **** local IconLabel = tklabel{image=Icon, anchor="center", width=32, height=32}; local TitleLabel = tklabel{Title; anchor="e", font="-*-helvetica-bold-o-*--16"}; local SubtitleLabel = tklabel{Subtitle; anchor="e", font="-*-helvetica-bold-r-*--12"}; local UpperSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; local ServSockIndicator = tklabel{image=CircleOffIcon, anchor="center", width=16, height=16}; local ServSockMessage = tkmessage{ "creating server socket"; width="40c", anchor="nw", font=TextFont }; local ServSockInfo = tkmessage{ "Address = (unknown), Port = (unknown)"; width="40c", anchor="nw", font=TextFont }; local RecvSockIndicator = tklabel{image=CircleOffIcon, anchor="center", width=16, height=16}; local RecvSockMessage = tkmessage{ "creating receiver socket (contacting server)"; width="40c", anchor="nw", font=TextFont }; local RecvSockInfo = tkmessage{ "Address = (unknown), Port = (unknown)"; width="40c", anchor="nw", font=TextFont }; local SendSockIndicator = tklabel{image=CircleOffIcon, anchor="center", width=16, height=16}; local SendSockMessage = tkmessage{ "creating sender socket (accepting receiver)"; width="40c", anchor="nw", font=TextFont }; local SendSockInfo = tkmessage{ "Address = (unknown), Port = (unknown)"; width="40c", anchor="nw", font=TextFont }; local SockSendIndicator = tklabel{image=CircleOffIcon, anchor="center", width=16, height=16}; local SockSendMessage = tkmessage{ "sending message"; width="40c", anchor="nw", font=TextFont }; local SockRecvIndicator = tklabel{image=CircleOffIcon, anchor="center", width=16, height=16}; local SockRecvMessage = tkmessage{ "receiving message"; width="40c", anchor="nw", font=TextFont }; local SockRecvData = tkmessage{ "got (unknown)"; width="40c", anchor="nw", font=TextFont }; local LowerSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; local StatusBar = tklabel{Status; anchor="w", font="-*-helvetica-medium-r-*--11"}; --**** construct application window **** local MainWindow = tkmain{ tkframe{ IconLabel, {side="left"}, TitleLabel, {side="top", fill="x"}, SubtitleLabel, {side="top", fill="x"} }, {side="top", fill="x"}, UpperSeparator, {side="top", fill="x"}, tkframe{ -- see below for some "fine-tuning" of this frame ServSockIndicator, ServSockMessage, "/", "x", ServSockInfo, "/", RecvSockIndicator, RecvSockMessage, "/", "x", RecvSockInfo, "/", SendSockIndicator, SendSockMessage, "/", "x", SendSockInfo, "/", SockSendIndicator, SockSendMessage, "/", SockRecvIndicator, SockRecvMessage, "/", "x", SockRecvData; geoman="grid" }, {side="top", fill="both", expand=1, pady=2}, LowerSeparator, {side="top", fill="x"}, StatusBar, {side="top", fill="x"} }; --**** display application window **** MainWindow:title(Title.." - "..Subtitle); MainWindow:show(); -- also triggers a window layout --MainWindow:resizable(0,0); -- disables window size changes --MainWindow:raise(); -- brings the window into the foreground --**** load any images for subsequent widget updates **** CircleOffIcon = tkeval("image create photo -file",CircleOffIcon)[1]; CircleOnIcon = tkeval("image create photo -file",CircleOnIcon)[1]; CircleOkIcon = tkeval("image create photo -file",CircleOkIcon)[1]; CircleCancelIcon = tkeval("image create photo -file",CircleCancelIcon)[1]; --**** it's now time to fine-tune the display **** tkeval('grid configure '..ServSockMessage.tkname..' -sticky "w"'); tkeval('grid configure '..ServSockInfo.tkname..' -sticky "w"'); tkeval('grid configure '..RecvSockMessage.tkname..' -sticky "w"'); tkeval('grid configure '..RecvSockInfo.tkname..' -sticky "w"'); tkeval('grid configure '..SendSockMessage.tkname..' -sticky "w"'); tkeval('grid configure '..SendSockInfo.tkname..' -sticky "w"'); tkeval('grid configure '..SockSendMessage.tkname..' -sticky "w"'); tkeval('grid configure '..SockRecvMessage.tkname..' -sticky "w"'); tkeval('grid configure '..SockRecvData.tkname..' -sticky "w"'); --**** provide an explicit method to terminate this program! **** MainWindow:protocol("WM_DELETE_WINDOW", "print('done...'); tkexit()"); --**** now start actual TCP experiments **** ServSockIndicator.image = CircleOnIcon; local CmdSocket,ErrMsg = bind("*",0); if (CmdSocket == nil) then ServSockIndicator.image = CircleCancelIcon; StatusBar.text="error: "..ErrMsg; tkwait(MainWindow.tkname); tkexit(); end; ServSockIndicator.image = CircleOkIcon; CmdAddr,CmdPort = CmdSocket:getsockname(); ServSockInfo.text = "(Address = "..CmdAddr..", Port = "..CmdPort..")"; RecvSockIndicator.image = CircleOnIcon; local InSocket,ErrMsg = connect("127.0.0.1",CmdPort); if (InSocket == nil) then RecvSockIndicator.image = CircleCancelIcon; StatusBar.text="error: "..ErrMsg; tkwait(MainWindow.tkname); tkexit(); end; RecvSockIndicator.image = CircleOkIcon; InAddr,InPort = InSocket:getsockname(); RecvSockInfo.text = "(Address = "..InAddr..", Port = "..InPort..")"; SendSockIndicator.image = CircleOnIcon; local OutSocket,ErrMsg = CmdSocket:accept(); if (OutSocket == nil) then SendSockIndicator.image = CircleCancelIcon; StatusBar.text="error: "..ErrMsg; tkwait(MainWindow.tkname); tkexit(); end; SendSockIndicator.image = CircleOkIcon; OutAddr,OutPort = OutSocket:getsockname(); SendSockInfo.text = "(Address = "..OutAddr..", Port = "..OutPort..")"; SockSendIndicator.image = CircleOnIcon; ErrMsg = OutSocket:send("Hello\n"); -- '\n' acts a message terminator if (ErrMsg ~= nil) then SockSendIndicator.image = CircleCancelIcon; StatusBar.text="error: "..ErrMsg; tkwait(MainWindow.tkname); tkexit(); end; SockSendIndicator.image = CircleOkIcon; SockRecvIndicator.image = CircleOnIcon; InSocket:timeout(4); local Message,ErrMsg = InSocket:receive(); if (Message ~= nil) then -- even in case of an error SockRecvData.text = "got \""..Message.."\""; end; if (ErrMsg ~= nil) then SockRecvIndicator.image = CircleCancelIcon; StatusBar.text="error: "..ErrMsg; tkwait(MainWindow.tkname); tkexit(); end; SockRecvIndicator.image = CircleOkIcon;