The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Ошибки в отладке простенького ftp клиента."
Отправлено my_way, 01-Сен-08 17:02 
Добрый день. Относительно недавно начал программировать под unix, опыта пока малова-то, поэтому, требуется помощь. Пишу простенький ftp клиент и пока что запнулся на следующем. Когда программа просто прогоняется всё выполняется корректно. Под отладчиком (работаю в SUSE 10.3 KDevelop) он после строчки fdopen и fclose иногда писал Cannot access memory 0x0
а иногда 0xfffffff причём появляются ошибки нерегулярно=(( Под suse 11 которая у меня дома такого вообще не происходит и никакие ошибки не вылазят.

Если что-то где-то можно написать красивее и грамотнее было бы здорово услышать предложения=)

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <cctype>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>

#include <unistd.h>
#include <iostream>
using namespace std;

#define MAX_SLEEP_CONNECT 128

bool             connect_retry(int &sock, const struct sockaddr *addr, socklen_t len);
struct addrinfo*     GetFtpAddr(const char *host);
int             ReturnSimpleRequest(int &sock, string* text);


bool connect_retry(int &sock, const struct sockaddr *addr, socklen_t len)
{
    if ((sock = socket(addr->sa_family, SOCK_STREAM, 0)) < 0)
        return false;

    int nsec = 0;
    /*
     *    Пытаемся установить соединение с экспоненциальной задержкой
     */
    for (nsec = 1; nsec <= MAX_SLEEP_CONNECT; nsec <<=1)
    {
        if (connect(sock, addr, len) == 0)
        {
            return true;
        }
        if (nsec <= MAX_SLEEP_CONNECT/2)
            sleep(nsec);
    }
    return false;
}

struct addrinfo* GetFtpAddr(const char *host)
{
    /*
      Функция возвращает адрес хоста по имени.(Адрес структуру addrinfo)
      Причём первый из его адресов.
    */
    int err = 0;
    
    struct addrinfo    address, hint, *spisok, *next;
    struct addrinfo *sinp = NULL;    

    address.ai_flags = AI_CANONNAME;
    address.ai_family = 0;
    address.ai_socktype = 0;
    address.ai_protocol = 0;
    address.ai_addrlen = 0;
    address.ai_canonname = NULL;
    address.ai_addr = NULL;
    address.ai_next = NULL;


    if ((err = getaddrinfo("ftp.freebsd.org", "ftp", &address, &spisok)) !=0 )
        printf("Err getaddrinfo: %s\n\n", gai_strerror(err));
    
    // Мы возвращаем первый же адресс который встречаем.
    
    for (next = spisok; next != NULL; next=next->ai_next)
    {
        if (next->ai_family == AF_INET)
        {
            sinp = next;
            break;
        }
    }
    
    /*
      По идее здесь должнен освобождать память выделенную под адреса
      ,тоесть freeaddrinfo(spisok); но почему-то я не знаю как это и где удобнее сделать.    
    */

    return sinp;
}

int main(int argc, char *argv[])
{
    int socket_ftp;
    
    int err = 0;
    
    const char *ad;
    char abuf[INET_ADDRSTRLEN];

    struct addrinfo *address = GetFtpAddr(argv[1]);
    
    if (address!=NULL)
    {
        struct sockaddr_in *sinp = (struct sockaddr_in *)address->ai_addr;
        ad = inet_ntop(AF_INET, &sinp->sin_addr, abuf, INET_ADDRSTRLEN);
        printf("Адрес %s  ", ad?ad:"не известен");
        printf("Порт %d", ntohs(sinp->sin_port));
        printf("\n");
    }
    if (!connect_retry(socket_ftp, address->ai_addr, address->ai_addrlen))
    {
        printf("\nНе успешно");
        exit(1);
    }

    string str = "error";
    int n = ReturnSimpleRequest(socket_ftp, &str);
    printf("Code: %d\n", n);
    
    close(socket_ftp);
    exit(0);
}
int ReturnSimpleRequest(int &sock, string *text)
{
  #define BUFLEN 100
  if (sock >0)
  {
    const char c = 'r';
    char buf[BUFLEN];
    char ccode[3];
    int code;
    
    FILE* socket_fd = NULL;

    if ((socket_fd = fdopen(sock, &c)) != NULL);
    {
        fgets(buf, 100, socket_fd);
        if (text!=NULL)        
        {
            text->clear();
            text->append(buf);
            printf("%s",text->c_str());
        }
        else
            printf("%s", buf);

        fclose(socket_fd);
        if (isdigit(buf[0]) && isdigit(buf[1]) && isdigit(buf[2]))
            return atoi(strncpy (ccode,buf,5));
        
    }
  }
  return -1;
}

 

Ваше сообщение
Имя*:
EMail:
Для отправки новых сообщений в текущей нити на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру