ftp over wifi

Тема в разделе "Проводная и беспроводная связь", создана пользователем fisheye, 12 ноя 2013.

  1. fisheye

    fisheye Нуб

    Привет всем.

    Стоит задача передачи файлов с Ардуино на компьютер с Линукс (Raspberry Pi) через wifi по протоколу ftp. Имеется: Arduino IDE 1.0.5, Arduino UNO R3, WiFi Shield, скетч, который умеет подключаться к wifi и передавать файл на сервер. Вернее, скетч должен это уметь, на деле он присоединяется, открывает ftp-сессию, логинится на сервер, начинает писать файл, потом передача обрывается с сообщением "Data disconnected". Файл на сервере создаётся, но не всё содержимое исходного файла там оказывается: исходный файл 7558 байт (текст скетча), а на сервере получается файл от 6560 до 7558 (2 раза из четырнадцати попыток) байт. Текст скетча в полученном файле получается с отрезанным финалом, размер потерянного текста случайно изменяется от попытки к попытке.

    Прошивка WiFi Shild'а обновлена, загружена прошивка, скачанная в комплекте с IDE.

    Что может быть причиной таких результатов?

    Скетч:
    Код (Text):
    /*
    This sketch connects to a Wifi network.
    Then it prints the  MAC address of the Wifi shield,
    the IP address obtained, and other network details.
    Then transfer file from SD card on ftp server (if press f)

    Circuit:
    * WiFi shield attached
    created 13 July 2010
    by dlf (Metodo2 srl)
    modified 31 May 2012
    by Tom Igoe -- WiFi part
    October 2012 by SurferTim -- ftp part
    October 2013 by Pashkot -- put the parts together (Arduino IDE 1.0.5, Arduino UNO R3)

    */
    #include <WiFi.h>
    #include <SD.h>
    #include <SPI.h>
    // comment out next line to write to SD from FTP server
    #define FTPWRITE

    char ssid[] = "dlink38";    //  your network SSID (name)
    char pass[] = "mypassowrd";  // your network password
    int status = WL_IDLE_STATUS;    // the Wifi radio's status

    // change to your server
    IPAddress server( 192, 168, 0, 106 );

    WiFiClient client;
    WiFiClient dclient;

    char outBuf[128];
    char outCount;

    // change fileName to your file (8.3 format!)
    char fileName[13] = "test.txt";

    void setup() {
      //Initialize serial and wait for port to open:
      Serial.begin(9600);
      //while (!Serial) {
        //; // wait for serial port to connect. Needed for Leonardo only
      //}
     
      pinMode(10,OUTPUT);
      digitalWrite(10,HIGH);

      if(SD.begin(4) == 0)
      {
        Serial.println(F("SD init fail"));        
      }
     
      // check for the presence of the shield:
      if (WiFi.status() == WL_NO_SHIELD) {
        Serial.println("WiFi shield not present");
        // don't continue:
        while(true);
      }
     
    // attempt to connect to Wifi network:
      while ( status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);

        // Connect to WPA/WPA2 network:  
        status = WiFi.begin(ssid, pass);

        // wait 10 seconds for connection:
        delay(10000);

        // you're connected now, so print out the data:
        Serial.print("You're connected to the network ");
        printCurrentNet();
        printWifiData();
        Serial.print("FTP server:");
        Serial.println(server);
        Serial.println(F("Ready. Press f or r"));
      }
    }

    void loop() {
      // check the network connection once every 10 seconds:
      //delay(10000);
      //printCurrentNet();
     
      byte inChar;

      inChar = Serial.read();

      if(inChar == 'f')
      {
        if(doFTP()) Serial.println(F("FTP OK"));
        else Serial.println(F("FTP FAIL"));
      }

      if(inChar == 'r')
      {
        readSD();  
      }

    }

    File fh;

    byte doFTP()
    {
    #ifdef FTPWRITE
      fh = SD.open(fileName,FILE_READ);
    #else
      SD.remove(fileName);
      fh = SD.open(fileName,FILE_WRITE);
    #endif

      if(!fh)
      {
        Serial.println(F("SD open fail"));
        return 0;  
      }

    #ifndef FTPWRITE
      if(!fh.seek(0))
      {
        Serial.println(F("Rewind fail"));
        fh.close();
        return 0;  
      }
    #endif

      Serial.println(F("SD opened"));

      if (client.connect(server,21)) {
        Serial.println(F("Command connected"));
      }
      else {
        fh.close();
        Serial.println(F("Command connection failed"));
        return 0;
      }

      if(!eRcv()) return 0;

      client.println(F("USER pi"));

      if(!eRcv()) return 0;

      client.println(F("PASS myftppassword"));

      if(!eRcv()) return 0;

      client.println(F("SYST"));

      if(!eRcv()) return 0;

      client.println(F("PASV"));

      if(!eRcv()) return 0;

      char *tStr = strtok(outBuf,"(,");
      int array_pasv[6];
      for ( int i = 0; i < 6; i++) {
        tStr = strtok(NULL,"(,");
        array_pasv[i] = atoi(tStr);
        if(tStr == NULL)
        {
          Serial.println(F("Bad PASV Answer"));  

        }
      }

      unsigned int hiPort,loPort;

      hiPort = array_pasv[4] << 8;
      loPort = array_pasv[5] & 255;

      Serial.print(F("Data port: "));
      hiPort = hiPort | loPort;
      Serial.println(hiPort);

      if (dclient.connect(server,hiPort)) {
        Serial.println(F("Data connected"));
      }
      else {
        Serial.println(F("Data connection failed"));
        client.stop();
        fh.close();
        return 0;
      }

    #ifdef FTPWRITE
      client.print(F("STOR "));
      client.println(fileName);
    #else
      client.print(F("RETR "));
      client.println(fileName);
    #endif

      if(!eRcv())
      {
        dclient.stop();
        return 0;
      }

    #ifdef FTPWRITE
      Serial.println(F("Writing"));

      byte clientBuf[64];
      int clientCount = 0;

      while(fh.available())
      {
        clientBuf[clientCount] = fh.read();
        clientCount++;

        if(clientCount > 63)
        {
          dclient.write(clientBuf,64);
          clientCount = 0;
        }
      }

      if(clientCount > 0) dclient.write(clientBuf,clientCount);

    #else
      while(dclient.connected())
      {
        while(dclient.available())
        {
          char c = dclient.read();
          fh.write(c);    
          Serial.write(c);
        }
      }
    #endif

      dclient.stop();
      Serial.println(F("Data disconnected"));

      if(!eRcv()) return 0;

      client.println(F("QUIT"));

      if(!eRcv()) return 0;

      client.stop();
      Serial.println(F("Command disconnected"));

      fh.close();
      Serial.println(F("SD closed"));
      return 1;
    }

    byte eRcv()
    {
      byte respCode;
      byte thisByte;

      while(!client.available()) delay(1);

      respCode = client.peek();

      outCount = 0;

      while(client.available())
      {
        thisByte = client.read();  
        Serial.write(thisByte);

        if(outCount < 127)
        {
          outBuf[outCount] = thisByte;
          outCount++;    
          outBuf[outCount] = 0;
        }
      }

      if(respCode >= '4')
      {
        efail();
        return 0;
      }

      return 1;
    }

    void efail()
    {
      byte thisByte = 0;

      client.println(F("QUIT"));

      while(!client.available()) delay(1);

      while(client.available())
      {
        thisByte = client.read();  
        Serial.write(thisByte);
      }

      client.stop();
      Serial.println(F("Command disconnected"));
      fh.close();
      Serial.println(F("SD closed"));
    }

    void readSD()
    {
      fh = SD.open(fileName,FILE_READ);

      if(!fh)
      {
        Serial.println(F("SD open fail"));
        return;  
      }

      while(fh.available())
      {
        Serial.write(fh.read());
      }

      fh.close();
    }


    void printWifiData() {
      // print your WiFi shield's IP address:
      IPAddress ip = WiFi.localIP();
        Serial.print("IP Address: ");
      Serial.println(ip);
       
      // print your MAC address:
      byte mac[6];
      WiFi.macAddress(mac);
      Serial.print("MAC address: ");
      Serial.print(mac[5],HEX);
      Serial.print(":");
      Serial.print(mac[4],HEX);
      Serial.print(":");
      Serial.print(mac[3],HEX);
      Serial.print(":");
      Serial.print(mac[2],HEX);
      Serial.print(":");
      Serial.print(mac[1],HEX);
      Serial.print(":");
      Serial.println(mac[0],HEX);
    }

    void printCurrentNet() {
      // print the SSID of the network you're attached to:
      Serial.print("SSID: ");
      Serial.println(WiFi.SSID());

      // print the MAC address of the router you're attached to:
      byte bssid[6];
      WiFi.BSSID(bssid);  
      Serial.print("BSSID: ");
      Serial.print(bssid[5],HEX);
      Serial.print(":");
      Serial.print(bssid[4],HEX);
      Serial.print(":");
      Serial.print(bssid[3],HEX);
      Serial.print(":");
      Serial.print(bssid[2],HEX);
      Serial.print(":");
      Serial.print(bssid[1],HEX);
      Serial.print(":");
      Serial.println(bssid[0],HEX);

      // print the received signal strength:
      long rssi = WiFi.RSSI();
      Serial.print("signal strength (RSSI):");
      Serial.println(rssi);

      // print the encryption type:
      byte encryption = WiFi.encryptionType();
      Serial.print("Encryption Type:");
      Serial.println(encryption,HEX);
      Serial.println();
    }
    Результат работы:
    Код (Text):
    Attempting to connect to WPA SSID: dlink38
    You're connected to the network SSID: dlink38
    BSSID: F0:7D:68:9F:E:5A
    signal strength (RSSI):-24
    Encryption Type:4

    IP Address: 192.168.0.107
    MAC address: 78:C4:E:2:9:98
    FTP server:192.168.0.106
    Ready. Press f or r
    SD opened
    Command connected
    220 (vsFTPd 2.3.5)
    331 Please specify the password.
    230 Login successful.
    215 UNIX Type: L8
    227 Entering Passive Mode (192,168,0,7,30,106).
    Data port: 7786
    Data connected
    150 Ok to send data.
    Writing
    Data disconnected
     
  2. fisheye

    fisheye Нуб

    На Arduino Mega2560 тот же результат
     
  3. Unixon

    Unixon Оракул Модератор

    Так сходу сложно сказать, в программе и в библиотеке вроде бы все разумно написано. Сначала подумал было на переполнение буфера контроллера на плате шилда, но библиотека пытается этого не допускать. Попробуйте натыкать побольше отладочного вывода через Serial.println() в интересующий кусок кода.
    Если не прояснится, тогда и внутрь библиотеки тоже натолкайте этих принтов и так непосредственно до места где происходит поворот в нетуда.
     
  4. fisheye

    fisheye Нуб

    Если б ещё хотя бы приблизительно пониммать, куда именно вставить Serial.println(), который мог бы помочь. Мопед, как говорится, не мой, я просто сложил вместе два скетча с официального сайта: один для подключения по WiFi, другой - ftp по Ethernet, о чём и написал в начале получившегося скетча в комментариях. А так-то я чайник, хотел применить Arduino для решения одной интересующей меня задачи, не вдаваясь в изучение. Казалось, что это будет просто. Похоже, что нет
     
  5. Unixon

    Unixon Оракул Модератор

    Да все правильно сделали. Проблема где-то в другом месте. Отладочный вывод нужно втыкать везде между интересующими строчками. Чтобы перед и после выполнения каждой строчки кода в проблемном месте МК отчитывался о ней в порт.
     
  6. fisheye

    fisheye Нуб

    Ну, вот интересное, на мой взгляд, место:
    Код (Text):

    byte clientBuf[64];
      int clientCount = 0;

      while(fh.available())
      {
        clientBuf[clientCount] = fh.read();
        clientCount++;

        if(clientCount > 63)
        {
          dclient.write(clientBuf,64);
          clientCount = 0;
        }
      }

      if(clientCount > 0) dclient.write(clientBuf,clientCount);
     
    Насколько я понимаю, именно вот в это месте и происходит запись.
    Кстати, я, по совету друзей по переписке с оффсайта, менял 64 на 32, но принципиально это ничего не поменяло: размер переданного файла стал всегда кратен 32 байтам, тогда как до изменения всегда был кратен 64 байтам.
    Что именно тут можно посмотреть через Serial.println()? Или, может, вообще не здесь? Почему передача прекращается по инициативе Arduino? Да, слишком много "чайниковых" вопросов, это от низкого уровня подготовки, мне самому это не нравится.
     
  7. Unixon

    Unixon Оракул Модератор

    Вы не знаете по какой причине прекращается передача, это и нужно выяснить. Посмотреть Serial.println() можно каким именно путем исполняется программа.
     
  8. fisheye

    fisheye Нуб

    Теория понятна, попробую проверить на практике. Может, есть какие-то предположения по поводу места, где "поворот не туда" наиболее вероятен? Где лучше его ловить?
     
  9. fisheye

    fisheye Нуб

    Хм, интересный результат, затрудняюсь его интерпретировать
    Изменил "записывающую" часть скетча вот таким образом:
    Код (Text):
    Serial.println("Writing");
      byte clientBuf[32];
      int clientCount = 0;
      int packNum = 0;

      while(file.available())
      {
        clientBuf[clientCount] = file.read();
        clientCount++;

        if(clientCount > 31)
        {
          packNum++;
          Serial.print("Packet number: ");
          Serial.println(packNum);
          dclient.write(clientBuf,32);
          clientCount = 0;
        }
      }

      if(clientCount > 0) dclient.write(clientBuf,clientCount);


      Serial.println("Stop here...");
      dclient.stop();
      Serial.println("Data disconnected");
     
    Результат (окончание):
    Код (Text):

    ...
    Packet number: 227
    Packet number: 228
    Packet number: 229
    Packet number: 230
    Packet number: 231
    Packet number: 232
    Packet number: 233
    Packet number: 234
    Packet number: 235
    Packet number: 236
    Stop here...
    Data disconnected
     
    Несложный подсчёт показывает, что 236 пакетов по 32 байта в сумме должный дать 7552 байт. Размер исходного файла 7558 байт, при подсчёте (или не при подсчёте?) я, видимо, теряю один пакет, а это значит, что Ардуино отдаёт всё, что должна (хм, или должен?).
    Размер файла, полученного на сервере, 7392 байт, что составляет ровно 231 пакет. Ушло 236 пакетов, пришло 231. Где могут потеряться остальные?
     
  10. Unixon

    Unixon Оракул Модератор

    Ну вот, теперь залазьте внутрь dclient.write(clientBuf,32); и там шпионьте за библиотечными нутрями. Если и там отладка покажет, что все отрабатывает как нужно, значит дело не в работе прошивки. Либо особенности передачи, либо приема. Еще на принимающей стороне неплохо бы запустить Wireshark и проснифать весь трафик. Пусть покажет, что туда на самом деле приходит.
     
  11. fisheye

    fisheye Нуб

    Сложновато для нуба. Я не знаю, что значит "залазьте внутрь dclient.write(clientBuf,32)". Существует какая-нибудь внятная методичка по этому вопросу? Вот про снифер понятно, а соваться в библиотечные внутренности боязно.
     
    Последнее редактирование: 4 дек 2013
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Почему боязно? Сделайте копию библиотеки, воткните внутрь отладочный вывод, изучите поведение.
    В любой момент сможете восстановить оригинальную версию библиотеки из копии.

    "залазьте внутрь dclient.write(clientBuf,32)" означает, что нужно изучить работу функции write класса WiFiClient. Вот эту: size_t WiFiClient::write(const uint8_t *buf, size_t size) { ... }. Она вызывает другие функции, в них тоже можно сунуться. Не бойтесь экспериментировать!
     
    Unixon нравится это.
  13. fisheye

    fisheye Нуб

    Поэкспериментирую. Вот только не совсем понимаю цель экспериментов. Что я должен увидеть? Уходят ли пакеты с Ардуино? Их количество? Содержание? Пакеты уходят и большинство из них (примерно 95%) достигает цели. Количество тоже известно. Остаётся содержание, так я понимаю? Или нужно выловить ошибки, возвращаемые библиотечными функциями?
     
  14. Unixon

    Unixon Оракул Модератор

    Нужно выловить отклонение от нормального исполнения программы. Если сбой передачи происходит по вине какого-то куска кода в библиотеке, вы это увидите.

    Например, в коде есть кусок

    bool everything_is_fine = get_connection_status();
    if (everything_is_fine)
    {
    send_next_block();
    }
    else
    {
    terminate_connection();
    }

    и вы знаете, что при нормальной передаче должна выполниться первая ветка.

    Втыкаете отладочный вывод и видите, что 124 раза функция прошла правильно, а на 125й раз взбрыкнула. Внедряетесь в виновника и так до последнего оператора, выясняете что именно не совпадает с ожидаемым.
     
  15. Megakoteyka

    Megakoteyka Оракул Модератор

    Строка dclient.write(clientBuf,32); вызывает интерес.
    Функция должна вернуть количество реально записанных байт.
    Можно ради эксперимента попробовать так:
    Код (Text):
    while(dclient.write(clientBuf,32) != 32)
      Serial.println("Write error!");
    и посмотреть на результат.
     
  16. fisheye

    fisheye Нуб

    Спасибо за рекомендации и советы, после экспериментов отпишусь
     
  17. fisheye

    fisheye Нуб

    Провёл первую серию экспериментов, из-за дефицита времени ограничился пока следующим изменением в коде скетча:
    Код (Text):

    #ifdef FTPWRITE
      Serial.println(F("Writing"));

      byte clientBuf[32];
      int clientCount = 0;
      int packNum = 0;

      while(fh.available())
      {
        clientBuf[clientCount] = fh.read();
        clientCount++;
     
        Serial.print("byte: ");
        Serial.println(clientBuf[clientCount]);

            if(clientCount > 31)
        {
          //dclient.write(clientBuf,64);
          dclient.write(clientBuf,32);
          clientCount = 0;
       
          while(dclient.write(clientBuf,32) != 32)
          Serial.println("Write error!");
       
          Serial.print("Packet number: ");
          Serial.println(packNum);
          packNum++;
        }
      }

      if(clientCount > 0)
      {
        dclient.write(clientBuf,clientCount);
      }

    #else
      while(dclient.connected())
      {
        while(dclient.available())
        {
          char c = dclient.read();
          fh.write(c);    
          Serial.write(c);
        }
      }
    #endif

      Serial.println("Stop here...");
      dclient.stop();
      Serial.println(F("Data disconnected"));
     
    В консоль, разумеется, посыпалась куча всего, ниже фрагменты из начала и конца вывода (комментарии мои, содержание передаваемого файла - текст скетча, перед которым вставлена строка "123 arduino"):
    Код (Text):

    ...
    Data connected
    150 Ok to send data.
    Writing
    byte: 0  //null
    byte: 0  //null
    byte: 106 //j
    byte: 9  //tab
    byte: 18  //DC2
    byte: 0  //null
    byte: 10  //lf
    byte: 3  //ETX
    byte: 122 //z
    byte: 1  //SOH
    byte: 7  //bell
    byte: 54  //6
    byte: 7  //bell
    byte: 54  //6
    byte: 0  //null
    byte: 12  //NP
    byte: 0  //null
    byte: 12  //NP
    byte: 0  //null
    byte: 2  //STX
    byte: 177 //±
    byte: 0  //null
    byte: 0  //null
    byte: 42  //+
    byte: 197 //Å
    byte: 3  //ETX
    byte: 96  //`
    byte: 0  //null
    byte: 7  //bell
    byte: 7  //bell
    byte: 8  //backspace
    byte: 128 //€
    Packet number: 0
    byte: 50  //2
    byte: 51  //3
    byte: 32  //space
    byte: 97  //a
    byte: 114 //r
    byte: 100 //d
    byte: 117 //u
    byte: 105 //i
    byte: 110 //n
    byte: 111 //o
    byte: 13  //cr
    byte: 10  //lf
    byte: 47  ///
    byte: 42  //*
    byte: 13  //cr
    byte: 10  //lf
    byte: 32  //space
    byte: 13  //cr
    byte: 10  //lf
    byte: 32  //space
    byte: 84  //T
    byte: 104 //h
    byte: 105 //i
    byte: 115 //s
    byte: 32  //space
    byte: 115 //s
    byte: 107 //k
    byte: 101 //e
    byte: 116 //t
    byte: 99  //c
    byte: 104 //h
    byte: 128 //€
    Packet number: 1
    byte: 99  //c
    byte: 111 //o
    byte: 110 //n
    byte: 110 //n

    ...

    Packet number: 234
    byte: 110 //n
    byte: 32  //space
    byte: 84  //T
    byte: 121 //y
    byte: 112 //p
    byte: 101 //e
    byte: 58  //:
    byte: 34  //"
    byte: 41  //)
    byte: 59  //;
    byte: 13  //cr
    byte: 10  //lf
    byte: 32  //space
    byte: 32  //space
    byte: 83  //S
    byte: 101 //e
    byte: 114 //r
    byte: 105 //i
    byte: 97  //a
    byte: 108 //l
    byte: 46  //.
    byte: 112 //p
    byte: 114 //r
    byte: 105 //i
    byte: 110 //n
    byte: 116 //t
    byte: 108 //l
    byte: 110 //n
    byte: 40  //(
    byte: 101 //e
    byte: 110 //n
    byte: 32  //space
    Packet number: 235
    byte: 114 //r
    byte: 121 //y
    byte: 112 //p
    byte: 116 //t
    byte: 105 //i
    byte: 111 //o
    Stop here...
    Data disconnected
    421 Data timeout. Reconnect. Sorry. //after aprox 5 min
     
    Судя по выводу в консоль, файл не был передан до конца, однако на сервере он оказался целиком, до самой последней скобки.
    Вторая попытка передачи файла принесла совсем уж непонятные результаты: вывод в консоль был полностью аналогичен первому разу, но на сервере оказался файл почти вдвое превышающий по размеру исходный. В файле на сервере оказались частично задублированы некоторые строки, пример ниже:
    Код (Text):

    123 arduino
    /*

    This sketch123 arduino
    /*

    This sketch connects to a Wifi network.
      connects to a Wifi network.
    Then it prints the  MAC address Then it prints the  MAC address of the Wifi sh$
    the IP addof the Wifi shield,
    the IP address obtained, and other networkress obtained, and other network det$
    Then transfer file f details.
    Then transfer file from SD card on ftp server (if prrom SD card on ftp server $

    Circuit:
    * WiFi shiess f)

    Circuit:
    * WiFi shield attached
     
    Третья попытка принесла такие же результаты, как и вторая. На это я остановился пока. Есть какие-то идеи по поводу такого поведения системы?
     
  18. Megakoteyka

    Megakoteyka Оракул Модератор

    Сделайте тестовый файл попроще. Наполните его, например, счетчиком: "0011223344..FF".
    Для начала пускай файл будет небольшого размера. Если он всегда будет передаваться корректно, увеличивайте размер.
    Анализируйте значения, возвращаемые функциями. Пишите комментарии к коду.
     
  19. fisheye

    fisheye Нуб

    Работа скетча не зависит от размера передаваемого файла. От содержания, по-моему, тоже.
    Исходный файл: 25 строк текста вида ххх temp 25, где ххх - номер строки 001, 002 и т.д., всего 398 байт
    Результат тот же - потеря нескольких байт в конце файла. Опыты проводились на Arduino UNO R3 и клоне Arduino Mega2560.
    Serial.println(dclient.write(clientBuf,32)) возвращает 32:
    Код (Text):

    ...
    byte: 41
    byte: 80
    byte: 2
    byte: 30
    byte: 6
    byte: 2
    byte: 255
    dclient.write: 32
    Packet number: 0
    byte: 48
    byte: 49
    byte: 9
    ...
     
    После нескольких попыток передачи появляются "задвоения" сторок в файле на сервере:
    Код (Text):

    001            temp    25
    002            temp    25
    001            temp    25
    002            temp    25
    003            temp    25
    004            temp    25
    003            temp    25
    004            temp    25
    005            temp    25
    006            temp    25
    005            temp    25
    006            temp    25
    007            temp    25
    008            temp    25
    007            temp    25
    008            temp    25
    009            temp    25
    ...
     
    Прям колдовство какое-то. Вывод каких функций может развеять чары и прояснить ситуацию?
     
  20. fisheye

    fisheye Нуб

    Вот интересующий меня кусок из библиотеки WiFiClient.cpp:
    Код (Text):

    size_t WiFiClient::write(uint8_t b) {
          return write(&b, 1);
    }

    size_t WiFiClient::write(const uint8_t *buf, size_t size) {
      if (_sock >= MAX_SOCK_NUM)
      {
          setWriteError();
          return 0;
      }
      if (size==0)
      {
          setWriteError();
          return 0;
      }


      if (!ServerDrv::sendData(_sock, buf, size))
      {
          setWriteError();
          return 0;
      }
      if (!ServerDrv::checkDataSent(_sock))
      {
          setWriteError();
          return 0;
      }

      return size;
    }
     
    Что надо сделать, чтобы увидеть возвращаемые значения? Я совсем не программист, извините за чайницкий вопрос