Problem bei der Portierung eines kurzen C Code-Blocks (Socket-Kommunikation) in die Objektive-C Welt.

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Problem bei der Portierung eines kurzen C Code-Blocks (Socket-Kommunikation) in die Objektive-C Welt.

    Ich bin (relativ verzweifelt) dabei, folgenden C-Code, der zur Datenübertragung mittels Sockels verwendet wird in die NSStream-Welt von Objective-C zu übersetzen.

    Wichtig wäre zum Beispiel, dass folgender reqCurrentTime Request mit meinem NSOutputStream funktioniert.
    Im Debugger bekomme ich die Rückmeldung, dass die NSStream Sockels erfolgreich geöffnet wurden, der Server (ein proprietäres System) antwortet jedoch nicht.

    Ich vermute, dass meine Portierung von EncodeField nicht korrekt ist und würde mich sehr freuen, wenn Ihr Tips oder Hinweise für mich hättet...


    Vielen herzlichen Dank im voraus!



    C-Code:

    Quellcode

    1. void EClientSocketBase::reqCurrentTime()
    2. {
    3. // not connected?
    4. if( !m_connected) {
    5. m_pEWrapper->error( NO_VALID_ID, NOT_CONNECTED.code(), NOT_CONNECTED.msg());
    6. return;
    7. }
    8. std::ostringstream msg;
    9. const int VERSION = 1;
    10. // send current time req
    11. ENCODE_FIELD( REQ_CURRENT_TIME);
    12. ENCODE_FIELD( VERSION);
    13. bufferedSend( msg.str());
    14. }
    Alles anzeigen



    Quellcode

    1. ///////////////////////////////////////////////////////////
    2. // encoders
    3. template
    4. void EClientSocketBase::EncodeField(std::ostream& os, T value)
    5. {
    6. os << value << '\0';
    7. }
    8. template<>
    9. void EClientSocketBase::EncodeField(std::ostream& os, bool boolValue)
    10. {
    11. EncodeField(os, boolValue ? 1 : 0);
    12. }
    13. template<>
    14. void EClientSocketBase::EncodeField(std::ostream& os, double doubleValue)
    15. {
    16. char str[128];
    17. snprintf(str, sizeof(str), "%.10g", doubleValue);
    18. EncodeField(os, str);
    19. }
    Alles anzeigen


    Konstanten-Definition:

    Quellcode

    1. const int REQ_CURRENT_TIME = 49;


    Das ist meine aktuelle Portierung:

    Quellcode

    1. @property (nonatomic, strong) NSInputStream *inputStream;
    2. @property (nonatomic, strong) NSOutputStream *outputStream;
    3. @synthesize inputStream=_inputStream;
    4. @synthesize outputStream=_outputStream;
    5. CFReadStreamRef readStream;
    6. CFWriteStreamRef writeStream;
    7. CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)@"localhost", 7496, &readStream, &writeStream); // "127.0.0.1" 7496 / 4001
    8. _inputStream = (__bridge NSInputStream *)readStream;
    9. _outputStream = (__bridge NSOutputStream *)writeStream;
    10. [_inputStream setDelegate:self];
    11. [_outputStream setDelegate:self];
    12. [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    13. [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    14. [_inputStream open];
    15. [_outputStream open];
    16. // Test Request:
    17. char str3[128]="49\0";
    18. NSString *nsstr3 = [[NSString alloc] initWithUTF8String:str3];
    19. NSData *data3 = [[NSData alloc] initWithData:[nsstr3 dataUsingEncoding:NSASCIIStringEncoding]];
    20. [_outputStream write:[data3 bytes] maxLength:[data3 length]];
    21. char str4[128]="1\0";
    22. NSString *nsstr4 = [[NSString alloc] initWithUTF8String:str4];
    23. NSData *data4 = [[NSData alloc] initWithData:[nsstr4 dataUsingEncoding:NSASCIIStringEncoding]];
    24. [_outputStream write:[data4 bytes] maxLength:[data4 length]];
    Alles anzeigen
    </int></bool>
  • Danke für Deine Nachricht.

    Leider hat das nicht geholfen. Ich habe es wie folgt implementiert:

    Quellcode

    1. - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
    2. {
    3. switch(eventCode) {
    4. case NSStreamEventNone:
    5. {
    6. NSLog(@"NSStreamEventNone");
    7. break;
    8. }
    9. case NSStreamEventOpenCompleted:
    10. {
    11. NSLog(@"NSStreamEventOpenCompleted");
    12. break;
    13. }
    14. case NSStreamEventErrorOccurred:
    15. {
    16. NSLog(@"NSStreamEventErrorOccurred");
    17. NSError *theError = [stream streamError];
    18. NSLog(@"Error reading stream! Error %i: %@",[theError code], [theError localizedDescription]);
    19. break;
    20. }
    21. case NSStreamEventEndEncountered:
    22. {
    23. NSLog(@"NSStreamEventEndEncountered");
    24. break;
    25. }
    26. case NSStreamEventHasBytesAvailable:
    27. {
    28. if (_iData == nil) {
    29. _iData = [[NSMutableData alloc] init];
    30. }
    31. uint8_t buf[1024];
    32. unsigned int len = 0;
    33. len = [(NSInputStream *)stream read:buf maxLength:1024];
    34. if(len) {
    35. [_iData appendBytes:(const void *)buf length:len];
    36. int bytesRead;
    37. bytesRead += len;
    38. NSString *str = [[NSString alloc] initWithData:_iData
    39. encoding:NSUTF8StringEncoding];
    40. NSLog(@"String received: %@",str);
    41. }
    42. else {
    43. NSLog(@"No data.");
    44. }
    45. break;
    46. }
    47. case NSStreamEventHasSpaceAvailable:
    48. {
    49. char str3[128]="49\0";
    50. NSString *nsstr3 = [[NSString alloc] initWithUTF8String:str3];
    51. NSData *data3 = [[NSData alloc] initWithData:[nsstr3 dataUsingEncoding:NSASCIIStringEncoding]];
    52. [_outputStream write:[data3 bytes] maxLength:[data3 length]];
    53. char str4[128]="1\0";
    54. NSString *nsstr4 = [[NSString alloc] initWithUTF8String:str4];
    55. NSData *data4 = [[NSData alloc] initWithData:[nsstr4 dataUsingEncoding:NSASCIIStringEncoding]];
    56. [_outputStream write:[data4 bytes] maxLength:[data4 length]];
    57. uint8_t *readBytes = (uint8_t *)[_oData mutableBytes];
    58. readBytes += _byteIndex; // instance variable to move pointer
    59. int data_len = [_oData length];
    60. unsigned int len = ((data_len - _byteIndex >= 1024) ?
    61. 1024 : (data_len-_byteIndex));
    62. uint8_t buf[len];
    63. (void)memcpy(buf, readBytes, len);
    64. len = [_outputStream write:(const uint8_t *)buf maxLength:len];
    65. _byteIndex += len;
    66. break;
    67. }
    68. }
    69. }
    Alles anzeigen


    Das Ergebnis ist leider das gleiche. :(

    Kann es nicht am encoding liegen?

    LG
  • DroneDeveloper schrieb:

    Weiß ich nicht, kenne den Server nicht.
    Was steht denn in der Konsole?

    So sieht die Konsolenausgabe (Debugger) aus:

    Quellcode

    1. 2012-01-15 12:35:46.645 Prototype[37110:fb03] NSStreamEventOpenCompleted
    2. 2012-01-15 12:35:46.646 Prototype[37110:fb03] NSStreamEventEndEncountered
    3. 2012-01-15 12:35:46.647 Prototype[37110:fb03] NSStreamEventOpenCompleted


    Die Gegenseite (Server) liefert leider keine Ausgabe, die verwertbar ist. Allerdings kann man erkennen, dass eine Socketverbindung dorthin aufgebaut wurde, da der Server einen eingehenden Verbindungsversuch signalisiert.
    Der Server scheint auch noch nicht zu antworten bzw. Daten zu liefern, da NSStreamEventHasBytesAvailable nicht ausgeführt wird.

    DANKE!!!
  • gritsch schrieb:

    hab den code nicht angesehen - aber warum willst du C-code portieren? Copy&Paste reicht ja ;)


    Der C-Code läuft zwar direkt, allerdings ist diese Lösung unbefriedigend, da der C-Code sehr alt ist (auf viele Files verteilt, schlecht strukturiert und daher kaum wartbar) und die ios-Runloop nicht unterstützt.
    Ich benötige nur einige kleine Teile davon und scheitere zur Zeit scheinbar am Datenformat (EncodeField-Portierung).