Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> передача файлов по TCP 
:(
    Опции темы
dumb
Дата 13.5.2008, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 1
Всего: 158



Цитата(nerdy_weirdie @  12.5.2008,  05:41 Найти цитируемый пост)
Бох ты мой, какой fread...
JohnnyQ только начинает трехколесный велосипед осваивать, а ты ему не без пафосной нотки мотоцикл предлагаешь.

Цитата(nerdy_weirdie @  12.5.2008,  23:32 Найти цитируемый пост)
Вы хоть представляете себе, как работают эти fread, fwrite?
хотя это похоже тобой и не предполагается, но код этих функций не относится к разряду тайных знаний.

могу задать встречный вопрос: ты представляешь себе, как работают эти CreateFileMapping, MapViewOfFile? попробуй на досуге файл на пару гигов обработать по приведенной тобой схеме.

Цитата(nerdy_weirdie @  12.5.2008,  23:32 Найти цитируемый пост)
Значительно удобнее.
удобнее написать непортабельный, испещренный системными вызовами код? это по сравнению с пятком строк с использованием fread? smile
PM MAIL   Вверх
nerdy_weirdie
Дата 13.5.2008, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Смешно вас слушать, ребзя. Для таких ликбезов есть интренет. Скажу лишь, что windows-приложения лучше писать используя непосредственно апишки ядра windows вместо уродливых мутантов созданных через пень-колоду с целью posix-совместимости на основе этих же апишек. Не бойтесь большого числа параметров  smile 

Простой пример:

FILE* f=fopen("c:\\myfile","w");
    if(f)
    {
        char szLine[] = "hi\r\n";
        fwrite(szLine,strlen(szLine),1,f); 
        fclose(f);
    }

Как ты думаешь, сколько и каких байт запишется в файл? 4 байта? Не угадал. А теперь представь, что ты сохранял файл с важными данными.  Этих трансляций-то можно избежать в бинарном режиме, но это лишний раз показывает кучу лишней бороды. О быстродействии и не заикайся.

Так вот подумай, что, как и почему.   smile 

Это сообщение отредактировал(а) nerdy_weirdie - 13.5.2008, 01:28
PM MAIL   Вверх
dumb
Дата 13.5.2008, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 1
Всего: 158



мне не нужно угадывать - твой простой пример запишет у меня 4 байта. потому что знаю, как работают эти функции. в отличие от.

Цитата(nerdy_weirdie @  13.5.2008,  01:48 Найти цитируемый пост)
Смешно вас слушать, ребзя. Для таких ликбезов есть интренет. Скажу лишь,
а свою смешливость и менторский тон оставь при себе. используй интернет сначала.

Добавлено через 2 минуты и 48 секунд
хорошо, что хоть исправил. smile
неисправленный "простой пример" был таким:
Код
char szLine[] = "hi\r\n";
fwrite(szLine,strlen(szLine),1,f);

PM MAIL   Вверх
nerdy_weirdie
Дата 13.5.2008, 01:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Всё равно всё пишет и читает ядро винды. И ты по прежнему доказываешь, что лучше дергать его не напрямую, а через посредников?

Это сообщение отредактировал(а) nerdy_weirdie - 13.5.2008, 01:41
PM MAIL   Вверх
dumb
Дата 13.5.2008, 02:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 1
Всего: 158



Цитата(nerdy_weirdie @  13.5.2008,  01:48 Найти цитируемый пост)
Этих трансляций-то можно избежать в бинарном режиме, но это лишний раз показывает кучу лишней бороды. О быстродействии и не заикайся.
уж прости, заикнусь: речь идет об отсылке файла по сети. а сеть пока еще, в большинстве случаев, по сравнению с дисковым обменом, является медленной средой передачи.

если ты наступил на грабли преждевременной оптимизации и тебе понравилось, то это вовсе не означает, что сие есть правильное и полезное занятие.

Цитата(nerdy_weirdie @  13.5.2008,  02:36 Найти цитируемый пост)
Всё равно всё пишет и читает ядро винды. И ты по прежнему доказываешь, что лучше дергать его не напрямую, а через посредников?
странно, что ты еще ассемблер не предложил, ну да ладно... о чем это мы? об ядре. так говоришь, напрямую его дергаешь?.. smile
родился еще один вопрос: ты представляешь себе количество системного кода, выполняющегося при вызове, например, ReadFile? можешь поисследовать, а когда оценишь, вернись к этому "бородатому посреднику" fread и сопоставь. точно не скажу, но полагаю, что посредник будет и по объему и по времени выполнения меньше 1% от общего кода. все те же грабли стучат нам по лбу.
PM MAIL   Вверх
nerdy_weirdie
Дата 13.5.2008, 03:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Ты все до одного свои аргументы просто выдумываешь? И так упёрто.. Тебе ведь опытный человек пишет. CRT полностью основана на winapi.
Сомневаюсь, что ты мне хоть спасибо за просвещение скажешь, но объясню:
fopen вызывает CreateFile (\microsoft visual studio 8\vc\crt\src\open.c, line 388)
fwrite вызывает  WriteFile (\Microsoft Visual Studio 8\VC\crt\src\write.c, line 297)
И так далее.
Обрати внимание, сколько там кода и вызовов.

И даже новичку намного проще и приятнее отправить и принять через сокет один единственный буфер, в котором лежит весь файл, чем дробить на куски, считать остаток, потом собирать на другом конце провода это. Скорость поиска дорожки на винчестере измеряется миллисекундами, за которые по обыкновенному адслю уходят десятки килобайт - для файлового сервера очень ощутимо smile 
PM MAIL   Вверх
ptr
Дата 13.5.2008, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(nerdy_weirdie @  13.5.2008,  06:44 Найти цитируемый пост)
Ты все до одного свои аргументы просто выдумываешь?

Это ты похоже все свои аргументы выдумываешь.

Цитата(nerdy_weirdie @  13.5.2008,  06:44 Найти цитируемый пост)
Тебе ведь опытный человек пишет.

И что опытный человек хорошего написал?

Цитата(nerdy_weirdie @  13.5.2008,  04:36 Найти цитируемый пост)
Всё равно всё пишет и читает ядро винды. И ты по прежнему доказываешь, что лучше дергать его не напрямую, а через посредников?

Больше скажу, так или иначе, все функции работают с ядром ;-) nerdy_weirdie, ты слышал такие слова как переносимость, кроссплатформенность?

Цитата(nerdy_weirdie @  13.5.2008,  06:44 Найти цитируемый пост)
И даже новичку намного проще и приятнее отправить и принять через сокет один единственный буфер, в котором лежит весь файл, чем дробить на куски, считать остаток, потом собирать на другом конце провода это.

1. И часто профессионалы так делают?
2. Быстрее, проще и приятнее не значит лучше.
2. На том конце всё равно придется собирать по-частям (данные не отправятся большим куском).

Цитата(nerdy_weirdie @  13.5.2008,  06:44 Найти цитируемый пост)
 для файлового сервера очень ощутимо  

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

Цитата(nerdy_weirdie @  13.5.2008,  06:44 Найти цитируемый пост)
Сомневаюсь, что ты мне хоть спасибо за просвещение скажешь, но объясню:fopen вызывает CreateFile (\microsoft visual studio 8\vc\crt\src\open.c, line 388)fwrite вызывает  WriteFile (\Microsoft Visual Studio 8\VC\crt\src\write.c, line 297)И так далее.

Зачастую при программировании fopen, fwritе и пр. ещё много раз заворачивают.


Это сообщение отредактировал(а) ptr - 13.5.2008, 08:59


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Олег2005
Дата 13.5.2008, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Hi all
И не надоело вам пересчитывать пальцы на руке - у кого их больше, тот и круче?
Хотя принципиально я все таки согласен - на АПИ оверхеда будет меньше-ИМХО
Однако при передаче по сети это совсем не критично......

Это сообщение отредактировал(а) Олег2005 - 13.5.2008, 12:11
PM MAIL WWW MSN   Вверх
ptr
Дата 13.5.2008, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(Олег2005 @  13.5.2008,  15:09 Найти цитируемый пост)
И не надоело вам пересчитывать пальцы на руке - у кого их больше, тот и круче?

Никогда не надоест smile

Это сообщение отредактировал(а) ptr - 13.5.2008, 17:41


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
MAKCim
Дата 13.5.2008, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(ptr @  13.5.2008,  08:43 Найти цитируемый пост)
Больше скажу, так или иначе, все функции работают с ядром ;-)

нет
Цитата(ptr @  13.5.2008,  08:43 Найти цитируемый пост)
На том конце всё равно придется собирать по-частям (данные не отправятся большим куском).

не обязательно
ключевое слово TSO



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
ptr
Дата 14.5.2008, 06:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(MAKCim @  13.5.2008,  22:09 Найти цитируемый пост)
нет

Ну да, погорячился  smile Скажу аккуратнее: большая часть функций работает с ядром smile 

Цитата(MAKCim @  13.5.2008,  22:09 Найти цитируемый пост)
не обязательноключевое слово TSO

Сегментация то всё равно происходит, только на другом уровне.




--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
MAKCim
Дата 14.5.2008, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(ptr @  14.5.2008,  06:48 Найти цитируемый пост)
Сегментация то всё равно происходит, только на другом уровне.

1. уровень NIC мы не контролируем
2. с точки зрения API данные будут приходить достаточно большими порциям
в случае, если файл не сильно большой, вполне возможно достаточно будет одной итерации для его получения


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
v1rtu0z
Дата 16.5.2008, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.4.2008
Где: Воронеж

Репутация: нет
Всего: нет



вот у меня есть функции для приема и передачи файлов.. там в них используется пара самописных функций, но все интуитивно понятно:
Код

int SendFile(SOCKET s,WIN32_FIND_DATA wfd)
{
    wcout << "Trying to send file " << wfd.cFileName << " ...";

    HANDLE hFile=CreateFile(wfd.cFileName,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(hFile != INVALID_HANDLE_VALUE)
    {
        DWORD bRd;
        char* sendbuf = new char[MAX_PATH];
        strcpy_s(sendbuf,bufSize,"");
        
        size_t i;        wcstombs_s(&i,sendbuf,(size_t)MAX_PATH,wfd.cFileName,(size_t)MAX_PATH);

        SendNBytes(s,sendbuf,MAX_PATH);
        strcpy_s(sendbuf,MAX_PATH,"");
        
        _itoa_s((int)(wfd.nFileSizeLow),sendbuf,(size_t)MAX_PATH,10);
        SendNBytes(s,sendbuf,MAX_PATH);
        strcpy_s(sendbuf,MAX_PATH,"");
        while (1)
        {
            ReadFile(hFile,sendbuf,bufSize,&bRd,NULL);
            if (bRd)
            {
                int sb = SendNBytes(s,sendbuf,bRd);
                //cout << "sended" << sb << "bytes" << endl;
                strcpy_s(sendbuf,MAX_PATH,"");
            }
            else
                break;
        }
        delete[] sendbuf;
        CloseHandle(hFile);
    }
    wcout << "sended" << endl;
    return 0;
}

и прием
Код

int ReceiveFile(SOCKET s)
{
    //получаем имя
    char* recvbuf = new char[MAX_PATH];
    ReceiveNBytes(s,recvbuf,MAX_PATH);
    
    cout << "Trying to receive file " << recvbuf << " ...";
    WCHAR* fName = new WCHAR[MAX_PATH];
    size_t i;
    mbstowcs_s(&i,fName,(size_t)MAX_PATH,recvbuf,(size_t)MAX_PATH);
    strcpy_s(recvbuf,MAX_PATH,"");
    ReceiveNBytes(s,recvbuf,MAX_PATH);
    int fSize = atoi(recvbuf);
    cout << fSize << " bytes...";

    HANDLE hFile=CreateFile(fName,
        GENERIC_WRITE,
        FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        DWORD bWr;
        int rb = 0;
        strcpy_s(recvbuf,MAX_PATH,"");
        for (;fSize>0;fSize-=bufSize)
        {
            if (fSize/bufSize)
            {
                rb = ReceiveNBytes(s,recvbuf,bufSize);
                if (rb)
                {
                    //cout << "received " << rb << " bytes" << endl;
                    if (WriteFile(hFile,recvbuf,rb,&bWr,NULL))
                    {
                        //cout << "written" << bWr << "bytes" << endl;
                    }
                }
            }
            else
            {
                rb = ReceiveNBytes(s,recvbuf,fSize);
                if (rb)
                {
                    //cout << "received " << rb << " bytes" << endl;
                    if (WriteFile(hFile,recvbuf,rb,&bWr,NULL))
                    {
                        //cout << "written" << bWr << "bytes" << endl;
                    }
                }
            }
            strcpy_s(recvbuf,MAX_PATH,"");
        }
        //CloseHandle(hFile);
    }
    cout << "received" << endl;
    delete[] recvbuf;
    delete[] fName;
    return 0;
}


PM MAIL ICQ   Вверх
Deepthroat
Дата 21.6.2008, 17:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 24.9.2007
Где: Outer Heaven

Репутация: нет
Всего: 2



Я в C++ не профи, но мое ИМХО - всегда лучше использовать кроссплатформенные функции сразу, чем потом переписывать код для другой системы.
PM MAIL WWW ICQ   Вверх
cmlwt
Дата 23.6.2008, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 22.6.2008

Репутация: нет
Всего: нет



Может пригодиться. У самого  была проблема считки бинарника 

Код


static long obtain_file_size( FILE *f )
{
   long file_size  = (~0);
   long position   = 0;

   if ( f != NULL )
   {
       position = ftell( f );

       if ( fseek( f, 0, SEEK_END ) == 0 )
           file_size = ftell( f );

       fseek( f, position, SEEK_SET );
   }

   return file_size;
}

static  char *get_file_content( const char *filename )
{
   FILE            *f;
    char   *content   = NULL;
   long            file_size;
   long            i;

   if ( filename == NULL )
       return NULL;

   f = fopen( filename, "rb" );
   if ( f != NULL )
   {
       if ( ( file_size = obtain_file_size( f ) ) != (~0) )
       {
           if ( ( content = ( char *)malloc( file_size ) ) != NULL )
           {
               i = 0;
               while ( !feof( f ) )
               {
                   // Если блок считан не полностью fread вернет 0
                   // т.е. если fread возвращает не 1, мы считали остатки файла
                   // или произошла другая ошибка, которую мы в данном случае не
                   // обрабатываем
                   if ( fread( content + i*BLOCK_SIZE, BLOCK_SIZE, 1, f ) != 1 )
                       break;
                   i++;
               }
           }
       }
       fclose( f );
   }

   return content;
}




Это сообщение отредактировал(а) cmlwt - 23.6.2008, 16:25
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1053 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.