如何使用 cfml 通过 telnet 进行通信?

问题描述 投票:0回答:1

我有一个仅通过 telnet 进行通信的游戏服务器。 我有一个 Lucee 服务器在同一个服务器机房运行,并且想编写一个可以向游戏服务器发送命令的小型 Web 应用程序。 看起来很简单,但几十个小时后,我经历了很多空谷歌搜索和各种尝试的方法(如 tst10),但效果不佳。

coldfusion telnet cfml lucee
1个回答
0
投票

我最终通过使用 Java 建立和管理 telnet 连接来实现这一点,并使用数据库表作为中间人,这样我的主线程就可以看到 telnet 连接所看到的内容。 我的工作代码如下。

此代码需要大量清理,但它是一个有效的概念证明,显示了如何完成它的基础知识。 希望其他有同样需求并且一直在用头撞墙的人会发现它很有用。

<cfcomponent>

    <cffunction returntype="Struct" name="telnetConnect" access="public" output="no">
        <cfargument name="SID"          type="numeric"  required="yes">
        <cfargument name="telnetAdd" type="string" required="yes">
        <cfargument name="telnetPort" type="numeric" required="yes">

        <cfset retVal           = structNew()>
        <cfset retVal.success   = true>

        <cftry>
            <cfparam name="application.telnet" default="#arrayNew()#">
            <cfparam name="application.telnet[arguments.SID]" default="#structNew()#">
            <cfparam name="application.telnet[arguments.SID].telnetClient" default="">
            <cfparam name="application.telnet[arguments.SID].lastData" default="#Now()#">

            <cfset application.telnet[arguments.SID].telnetData = "">
            <cfset application.telnet[arguments.SID].isReading  = false>

            <cfscript>
                // If there is an existing connection for this server; close it.
                telnetClose(arguments.SID);
                sleep(25);

                // Load the Apache Commons Net TelnetClient class
                application.telnet[arguments.SID].telnetClient = createObject("java", "org.apache.commons.net.telnet.TelnetClient").init();

                // Connect to the Telnet server
                application.telnet[arguments.SID].telnetClient.connect(arguments.telnetAdd, arguments.telnetPort);

                // Get input and output streams
                application.telnet[arguments.SID].inputStream = application.telnet[arguments.SID].telnetClient.getInputStream();
                application.telnet[arguments.SID].outputStream = application.telnet[arguments.SID].telnetClient.getOutputStream();
            </cfscript>

            <cfcatch>
                <cfset retVal.success   = false>
                <cfset retVal.cfcatch   = cfcatch>
            </cfcatch>
        </cftry>

        <cfreturn retVal />
    </cffunction>

    <cffunction returntype="Struct" name="telnetSend" access="public" output="no">
        <cfargument name="SID"          type="numeric"  required="yes">
        <cfargument name="message"      type="string"   required="yes">

        <cfset retValSend           = structNew()>
        <cfset retValSend.success   = true>

        <cftry>

            <cfscript>
                command = "#arguments.message##chr(13)#";
                application.telnet[arguments.SID].outputStream.write(command.getBytes());
                application.telnet[arguments.SID].outputStream.flush();
            </cfscript>

            <cfcatch>
                <cfset retValSend.success   = false>
                <cfset retValSend.cfcatch   = cfcatch>
            </cfcatch>
        </cftry>

        <cfreturn retValSend />
    </cffunction>

    <cffunction returntype="Struct" name="telnetRead" access="public" output="no">
        <cfargument name="SID" type="string" required="yes">

        <cfset var retVal = structNew()>
        <cfset retVal.success = true>

        <cftry>
            <cfset application.telnet[arguments.SID].isReading  = true>

            <cfscript>
                // Create an InputStreamReader from the InputStream
                inputStreamReader = createObject("java", "java.io.InputStreamReader").init(application.telnet[arguments.SID].inputStream, "UTF-8");
                
                // Create a char array for reading
                charBuffer = createObject("java", "java.lang.reflect.Array").newInstance(createObject("java", "java.lang.Character").TYPE, 1024);
                charsRead = 0;
                totalRead = 0;
                maxRead = 5120; // Max chars to read at a time
            </cfscript>

            <cfloop condition="totalRead lt maxRead">
                <cfset charsRead = inputStreamReader.read(charBuffer, 0, 1024)>
                <cfif charsRead is -1>
                    <cfbreak>
                </cfif>

                <cfset dataChunk = createObject("java", "java.lang.String").init(charBuffer, 0, charsRead)>
                <cfset totalRead += charsRead>

                <cfset application.telnet[arguments.SID].telnetData &= dataChunk>

                <cfif dataChunk contains chr(13)>
                    <cfloop list="#dataChunk#" delimiters="#chr(13)#" index="thisLine">
                        <cfquery name="saveChunk">
                            insert into telnetMessages  (mdate, message)
                                        values          (Now(),
                                                         <cfqueryparam cfsqltype="varchar" value="#thisLine#">)
                        </cfquery>
                        <cfset application.telnet[arguments.SID].lastData   = Now()>
                    </cfloop>
                <cfelse>
                    <cfquery name="saveChunk">
                        insert into telnetMessages  (mdate, message)
                                    values          (Now(),
                                                     <cfqueryparam cfsqltype="varchar" value="#dataChunk#">)
                    </cfquery>
                    <cfset application.telnet[arguments.SID].lastData   = Now()>
                </cfif>
            </cfloop>

            <cfset application.telnet[arguments.SID].isReading  = false>

            <cfcatch>
                <cfset application.telnet[arguments.SID].isReading  = false>
                <cfset retVal.success = false>
                <cfset retVal.cfcatch = cfcatch>
            </cfcatch>
            <cffinally>
                <cfset application.telnet[arguments.SID].isReading  = false>
            </cffinally>
        </cftry>

        <cfreturn retVal />
    </cffunction>

    <cffunction returntype="Struct" name="telnetClose" access="public" output="no">
        <cfargument name="SID"          type="numeric"  required="yes">

        <cfset retValClose          = structNew()>
        <cfset retValClose.success  = true>

        <cftry>
            <cfscript>
                if (application.telnet[arguments.SID].telnetClient.isConnected()) {
                    application.telnet[arguments.SID].telnetClient.disconnect();
                }
            </cfscript>

            <cfcatch>
                <cfset retValClose.success  = false>
                <cfset retValClose.cfcatch  = cfcatch>
            </cfcatch>
        </cftry>

        <cfreturn retValClose />
    </cffunction>

</cfcomponent>
© www.soinside.com 2019 - 2024. All rights reserved.