Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получение бинарного файла через сокет (C#) 
:(
    Опции темы
Lord Dagger
Дата 8.9.2005, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здраствуйте! Я написал небольшую программу для загрузки файлов, но возникла следующая проблема: как отделить заголовок от данных?smile
Пока я делаю это простым парсингом:
Код

Socket connection = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
                IPHostEntry hostInfo = Dns.Resolve( TheUri.Host );
                IPEndPoint ep =  new IPEndPoint(hostInfo.AddressList[0] , TheUri.Port );
                connection.Connect( ep );


                //4. Sending request and reading response
                NetworkStream ns = new NetworkStream( connection,  FileAccess.ReadWrite );
                StreamReader strmReader = new StreamReader( ns ); 
                StreamWriter strmWriter = new StreamWriter( ns );

                byte[] buf = new byte[ 1000000 ];
                byte[] her = new byte[ 1000000 ];
                FileStream file = new FileStream( "exp.gif",FileMode.Create);
                BinaryWriter w = new BinaryWriter(file);

                strmWriter.Write( Head );
                strmWriter.Flush();

                // Чтение заголовка
                int bytes = 0;
                int state = 0;
                while (ns.Read( buf,0, connection.Available ) != -1)
                {
                    switch (buf[ bytes ])
                    {
                        case 13:
                            state++;
                            break;
                        case 10:
                            state++;
                            break;
                        default:
                            state = 0;
                            break;
                    }
                    if (state == 4)
                    {
                        Array.Copy(buf,bytes,her,0,1000000-bytes);
                        break;
                    }
                    bytes++;
                }
                
                bytes = 0;
                
                w.Write(her, 1, 312); // пока размер итогового файла задется вручную
            
                file.Flush();
                file.Close();

Но возникает проблема: скачиваемый файл не может быть больше размеров буфера.
Как преодолеть это?
MSDN читал, в google искал.
Нашел много всего хорошего, но не ответ на этот вопрос...
Буду очень благодарен за помощь!

Это сообщение отредактировал(а) Lord Dagger - 8.9.2005, 14:30
--------------------
(+)  
PM MAIL WWW ICQ   Вверх
Mad
Дата 8.9.2005, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Lord Dagger
1. Судя по коду, запрос этот ты на HTTP сервер шлеш. Но может и нет, так что укажи какой протокол
2. Если протокол HTTP, то лечше использовать WebRequest
3. Для приема произволной длины в памяти, используй MemoryStream



--------------------
user posted image
PM MAIL   Вверх
Lord Dagger
Дата 8.9.2005, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Mad
1. Да, протокол http
2. Этовроде бы другой уровень абстракции?
3. Это мне не нужно...
Если файл занимает 100 мб, то гораздно удобнее читать его порциями по 1 мб
Фактически, вопрос формулируется так:
Как правильно организовать считывание файла через network stream с использованием буфера, значительно меньше длины файла?
--------------------
(+)  
PM MAIL WWW ICQ   Вверх
Mad
Дата 8.9.2005, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(Lord @ 8.9.2005, 13:52)
Да, протокол http

тогда у тебя и конец заголовка определяеться неправильно smile
каждая строка в заголовке ответа HTTP сервера заканчиваеться 13-13-10 а сам заголовок заканчиваеться 13-13-10-13-13-10

а код получаеться такой :

Код

                byte[] buf = new byte[ 4096 ];
                byte[] head = new byte[ 1000000 ];
                FileStream file = new FileStream( "exp.gif",FileMode.Create);
                BinaryWriter w = new BinaryWriter(file);

                strmWriter.Write( Head );
                strmWriter.Flush();

                // Чтение заголовка
                int bytes = 0;
                while (ns.Read( head, bytes, 1 ) != -1)
                {
                    if (bytes > 5 && head[bytes] = 10 && head[bytes-1] == 13 && head[bytes-2] == 13
                        && head[bytes-3] == 10 && head[bytes-4] == 13 && head[bytes-5] == 13)
                        break;
                    bytes++;
                }
                
                int readed = ns.Read(buf, 0, 4096);
                while (readed > -1)
                {                
                    w.Write(buf, 0, readed);
                    readed = ns.Read(buf, 0, 4096);
                }

                ns.Close();
                w.Close();


Это сообщение отредактировал(а) Mad - 8.9.2005, 15:10


--------------------
user posted image
PM MAIL   Вверх
Lord Dagger
Дата 8.9.2005, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Mad
Спасибо, но код не работает... smile
Код

if (bytes > 5 && head[bytes] = 10 && head[bytes-1] == 13 && head[bytes-2] == 13
                        && head[bytes-3] == 10 && head[bytes-4] == 13 && head[bytes-5] == 13)

Приводит к:
(265): Operator '&&' cannot be applied to operands of type 'bool' and 'byte'

Если записать
Код

if ((bytes > 5 && head[bytes] == 10) && (head[bytes-1] == 13 && head[bytes-2] == 13)
                        && (head[bytes-3] == 10 && head[bytes-4] == 13) && head[bytes-5] == 13)

получается бесконечный цикл...
--------------------
(+)  
PM MAIL WWW ICQ   Вверх
Mad
Дата 8.9.2005, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(Lord @ 8.9.2005, 14:43)
Operator '&&' cannot be applied to operands of type 'bool' and 'byte'

там просто опечатка получилась smile

Цитата(Lord @ 8.9.2005, 14:43)
получается бесконечный цикл...

модет винда делает маленькое преобразование, попробуй так

Код

if (bytes > 3 && head[bytes] == 10 && head[bytes-1] == 13 && head[bytes-2] == 10 && head[bytes-3] == 13) 



--------------------
user posted image
PM MAIL   Вверх
Lord Dagger
Дата 8.9.2005, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Mad
Получилось, теперь работает, но проблема здесь:
Код

                int readed = ns.Read(buf, 0, 4096);
                while (readed > -1)
                {                
                    w.Write(buf, 0, readed);
                    readed = ns.Read(buf, 0, 4096);
                }

readed всегда получает значение 0, когда считывание файла прекращается.
Везде в примерах тем не менее я видел -1 smile
что бы это значило?

P.S. Файл считывается нормально, только выполнение программы не прекращаетсяsmile
--------------------
(+)  
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 8.9.2005, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


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

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



Цитата(Lord @ 8.9.2005, 16:10)
Везде в примерах тем не менее я видел -1
что бы это значило?

Скорее всего, это ошибка.


--------------------
user posted image
PM MAIL WWW   Вверх
Lord Dagger
Дата 8.9.2005, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



mr.DUDA
Ясно.. Спасибо всем за помощь, вы мне здорово помогли!
Неплохо было бы на будущее написать туториал в C# FAQ
Подобные есть, но под Java:
использование сокетов в Java
--------------------
(+)  
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




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


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

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