2015-09-12 1 views
8

Я пытаюсь написать фрагменты Swift для отправки команд Telnet, но сначала мне нужно войти в систему.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. Все идет нормально.

Я написал модуль Telnet для Android, поэтому служба OSX Telnet работает правильно. Это означает, что я вижу login: и password: выходы, поэтому я могу справиться с этим.

Теперь я застрял с прошивкой Swift, я Googled и нашел очень хорошее решение, которое должно работать в моем случае:

Так что я написал свою домашнюю работу :

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)") 
    } 

} 

Контроль обратного вызова потока meth од от 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 streamили я ошибаюсь?. Это должно быть NSStreamEvent.HasBytesAvailable состояние или я ошибаюсь?

Когда я звоню sendMessage("snags"), я получаю ответ в stream, который выпадает на case NSStreamEvent.HasSpaceAvailable. Что это значит?


Мои ожидаемые результаты: при подключении я должен получить login: выход, но не получить ничего.

+0

@Brian, почему вы удалили 'Swift iOS' из названия? этот вопрос относится к iOS Swift и не точно telnet – snaggs

+0

Включение тегов в заголовок является избыточным и создает беспорядок. Теги будут следить за тем, что очевидно, что такое темы. Вы можете прочитать больше в [этот мета-вопрос] (http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles). – Brian

+0

NSStream даст вам много головной боли, я действительно рекомендую использовать сторонние структуры, такие как [CocoaAsyncSocket] (https://github.com/robbiehanson/CocoaAsyncSocket) Робби Хэнсона. Все, что вам нужно сделать, это включить 'GCDAsyncSocket.h 'в вашем' bridge-header.h' – Xrait

ответ

-1

Вы почти сделали вывод о NSStreamDelegate, но вам нужно знать спецификацию протокола rfc 854 telnet.

Предшествующая связь требует согласования telnet между хостом и вашим кодом.

В случае вашего перезвонить в «NSStreamEvent.HasBytesAvailable», дамп буфера, превращающего в NSData, как

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

вы получите

<fffd18ff fd20fffd 23fffd27 fffd24> 

который телнет переговоры, которые вы должны ответить по к спецификации.

2-й вопрос.

NSStreamEvent.HasSpaceAvailable означает, что «Логическое значение, указывающее, может ли приемник быть записан».

Прежде чем отправлять сообщение через NSOutputStream, вы должны проверить свойство hasSpaceAvailable NSOutputStream в методе sendMessage.

Или используйте очередность для отправки данных и отправки их при падении на NSStreamEvent.HasBytesAvailable, это моя рекомендация.

См. Этот ответ. How to use NSInputStream and NSOutputStream

+0

При подключении я получаю 'NSStreamEvent.OpenCompleted' случай, после отправки запроса я получаю' NSStreamEvent.HasSpaceAvailable', но никогда 'NSStreamEvent.HasBytesAvailable' – snaggs

+0

Ничего не происходит, когда я запускаю' self.outputStream.write (& buffer, maxLength: buffer .count) ' – snaggs