ios – Telnet获取空输出并且没有登录/密码

我尝试编写 Swift片段来向Telnet发送命令,但我需要先登录.

在OSX上我生成了一个Telnet服务:launchctl load -F /System/Library/LaunchDaemons/telnet.plist.之后我能够从其他计算机连接到IP:XXX.XXX.X.XXX端口23.

例如,从Windows 7:

telnet XXX.XXX.X.XXX 23
.....
Darwin/BSD (fess.local) (ttys009)

login: snaggs
Password:xxxxxx

snaggs:~ lur$

在命令行中,Telnet要求我输入用户名和密码.之后我可以运行任何Linux命令.到现在为止还挺好.

我为Android编写了Telnet模块,因此OSX Telnet服务正常运行.这意味着我看到登录:和密码:输出,所以我能够处理它.

现在我坚持使用iOS Swift,我用Googled找到了非常好的解决方案,应该适用于我的情况:

> receiving-data-from-nsinputstream-in-swift
> using-sockets-in-swift-like-in-java

所以我写了我的家庭作品:

class TelnetClient : NSObject,NSStreamDelegate{

    private var inputStream: NSInputStream!
    private var outputStream: NSOutputStream!


func initNetworkCommunication(){
        let host : CFString = "XXX.XXX.X.XXX"
        let port : UInt32 = 23
        var readstream : Unmanaged<CFReadStream>?
        var writestream : Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,host,port,&readstream,&writestream)

 //        var _inputStream: NSInputStream? 
 //        var _outputStream: NSOutputStream? 
 //        NSStream.getStreamsToHostWithName("XXX.XXX.X.XXX",port: 23,inputStream: &_inputStream,outputStream: &_outputStream) 
 //        self.inputStream = _inputStream! 
 //        self.outputStream = _outputStream!


        self.inputStream = readstream!.takeRetainedValue()
        self.outputStream = writestream!.takeRetainedValue()

        self.inputStream.delegate = self
        self.outputStream.delegate = self


        self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(),forMode: NSDefaultRunLoopMode)
        self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(),forMode: NSDefaultRunLoopMode)

        self.inputStream.open()
        self.outputStream.open()

    }


func sendMessage(message:String){

    let data: NSData = message.dataUsingEncoding(NSASCIIStringEncoding,allowLossyConversion: true)! //NSUTF8StringEncoding
    let stream: NSInputStream = NSInputStream(data: data)

        var buffer = [UInt8](count: 8,repeatedValue: 0)
        stream.open()

        if stream.hasBytesAvailable {
          let result :Int = stream.read(&buffer,maxLength: buffer.count)
        }
        self.outputStream.write(&buffer,maxLength: buffer.count)

        println("wrote to Server: \(message)")
    }

}

来自NSStreamDelegate的流回调覆盖方法:

func stream(aStream: NSStream,handleEvent eventCode: NSStreamEvent) {
        switch (eventCode){
        case NSStreamEvent.ErrorOccurred:
            NSLog("ErrorOccurred")
            break
        case NSStreamEvent.EndEncountered:
            NSLog("EndEncountered")
            break
        case NSStreamEvent.None:
            NSLog("None")
            break
        case NSStreamEvent.HasBytesAvailable:
            NSLog("HasBytesAvaible")
            // ... NEVER ENTERS HERE
            var buffer = [UInt8](count: 4096,repeatedValue: 0)
        if ( aStream == self.inputStream){

            while (self.inputStream.hasBytesAvailable){
                var len = self.inputStream.read(&buffer,maxLength: buffer.count)
                if(len > 0){
                    var output = NSString(bytes: &buffer,length: buffer.count,encoding: NSUTF8StringEncoding)
                    if (output != ""){
                        NSLog("server said: %@",output!)
                    }
                }
            }
        }
            break
        //case NSStreamEvent.allZeros:
        //    NSLog("allZeros")
        //     break
        case NSStreamEvent.OpenCompleted:
            NSLog("OpenCompleted") // <-- called on initialisation
            break
        case NSStreamEvent.HasSpaceAvailable:
            NSLog("HasSpaceAvailable")
            break
        default:
             NSLog("default")
             break

        }
    }

首先,当我尝试调用initNetworkCommunication()时没有任何反应.我希望调用func流或者我错了?它应该是NSStreamEvent.HasBytesAvailable状态还是我错了?

当我调用sendMessage(“snags”)时,我得到流中的响应,该响应属于NSStreamEvent.HasSpaceAvailable案例.这是什么意思?

我的预期结果:在连接上我应该登录:输出但什么也得不到.

解决方法

你几乎完成了关于NSStreamDelegate,但你需要知道’rfc 854 telnet协议规范’.

在通信之前,需要在主机和代码之间进行telnet协商.

在你的回调’NSStreamEvent.HasBytesAvailable’的情况下,转储你的缓冲区,转换为NSData,就像

NSLog( "%@",NSData(bytes: buffer,length: len) )

你会得到

<fffd18ff fd20fffd 23fffd27 fffd24>

这是telnet协商,你必须根据规范做出回应.

第二个问题.

NSStreamEvent.HasSpaceAvailable意味着’一个布尔值,指示是否可以写入接收器.’

在通过NSOutputStream发送消息之前,必须在“sendMessage”方法中检查NSOutputStream的hasSpaceAvailable属性.

或者使用队列来发送数据并在NSStreamEvent.HasBytesAvailable上发送它,这是我的建议.

看到这个答案.
How to use NSInputStream and NSOutputStream

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...