Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.56/169: Рейтинг темы: голосов - 169, средняя оценка - 4.56
37 / 32 / 4
Регистрация: 23.01.2009
Сообщений: 141

Передача файлов по TCP. Интерестный вопрос

04.02.2009, 00:43. Показов 33246. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот такое клиент-сервер приложение:
Клиент:
C#
1
2
3
4
5
6
7
8
9
10
11
  TcpClient eclient = new TcpClient("localhost",34567);
            NetworkStream writerStream = eclient.GetStream();
            BinaryFormatter format = new BinaryFormatter();
            byte[] buf = new byte[1024*1024 ];
            int count;
            FileStream fs = new FileStream("111.txt", FileMode.Open);
            BinaryReader br = new BinaryReader(fs);
             while ((count = br.Read(buf, 0, 1024*1024 )) > 0)
            {
                format.Serialize(writerStream, buf);
            }
Сервер:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TcpListener clientListener = new TcpListener(34567);
clientListener.Start();
TcpClient client = clientListener.AcceptTcpClient();
NetworkStream readerStream = client.GetStream();
BinaryFormatter outformat = new BinaryFormatter();
             FileStream fs = new FileStream("111.txt", FileMode.OpenOrCreate);
BinaryWriter bw=new BinaryWriter(fs);
           
      
byte[] buf  = (byte[] )(outformat.Deserialize(readerStream));
bw.Write(buf);
bw.Close();
fs.Close();
Console.ReadLine();
Но таким способом сервер считывает поток только 1 раз. Т.е. в данном случае поток 1 мб, если файл весит больше, или я хочу разбить поток на фрагменты, то я передать не могу. Вопрос: как сделать цикл приёма на сервере?

Добавлено через 49 минут 4 секунды
Всё решил))
Клиент:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
 TcpClient eclient = new TcpClient("localhost",34567);
            NetworkStream writerStream = eclient.GetStream();
            BinaryFormatter format = new BinaryFormatter();
            byte[] buf = new byte[1024 ];
            int count;
            FileStream fs = new FileStream("111.txt", FileMode.Open);
            BinaryReader br = new BinaryReader(fs);
            long k = fs.Length;//Размер файла.
            format.Serialize(writerStream, k.ToString());//Вначале передаём размер
             while ((count = br.Read(buf, 0, 1024 )) > 0)
            {
                format.Serialize(writerStream, buf);//А теперь в цикле по 1024 байта передаём файл
            }
Сервер:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cpListener clientListener = new TcpListener(34567);
clientListener.Start();
    TcpClient client = clientListener.AcceptTcpClient();
    NetworkStream readerStream = client.GetStream();
    BinaryFormatter outformat = new BinaryFormatter();
    FileStream fs = new FileStream("111.jpg", FileMode.OpenOrCreate);
    BinaryWriter bw = new BinaryWriter(fs);
    int count;
    count = int.Parse(outformat.Deserialize(readerStream).ToString());//Получаем размер файла
            int i=0;
            for (; i < count;i += 1024 )//Цикл пока не дойдём до конца файла
            {
 
                byte[]  buf = (byte[])(outformat.Deserialize(readerStream));//Собственно читаем из потока и записываем в файл
                bw.Write(buf);
            }
            
    bw.Close();
    fs.Close();
 
 
 
Console.ReadLine();
Только в данном случает примет один файл. А хотелось бы чтобы сервер постоянно работал и принимал. Бесконечный цикл?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.02.2009, 00:43
Ответы с готовыми решениями:

Передача файлов через TCP
Пишу клиент серверное приложение. Клиент должен отправлять файлы. Сервер принимать. Использую TcpClient и NetworkStream. Сначала файл...

TCP сокет. Передача больших файлов
Собственно пишу курсовую работу. Что-то на подобии DROPBOX. Передача файлов шифрование и всё такое) Реализовав сокет TCP у меня...

Передача файлов по TCP и запись данных в переменную
Нашел интересную тепку - ссылка И вот такой вопрос, как в сервере записать получаемый файл в переменную?

25
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
07.04.2010, 14:34
Студворк — интернет-сервис помощи студентам
borN_free, в клиенте:
Цитата Сообщение от artstalker Посмотреть сообщение
count = br.Read(buf, 0, 1024
при последнем чтении из файла (т.е. чтение последних 1024 байта данных файла), данных может оказаться меньше чем 1024. Кол-во реально прочитанных байт находится в переменной count. Получается, что на последнем проходе в буфере находится N байт данных и 1024-N - нулей. Поэтому в format нужно передавать не весь buf, а только часть данных длинной равной count.
0
3 / 3 / 0
Регистрация: 18.03.2010
Сообщений: 5
07.04.2010, 22:21
Цитата Сообщение от Green Посмотреть сообщение
borN_free, в клиенте:

при последнем чтении из файла (т.е. чтение последних 1024 байта данных файла), данных может оказаться меньше чем 1024. Кол-во реально прочитанных байт находится в переменной count. Получается, что на последнем проходе в буфере находится N байт данных и 1024-N - нулей. Поэтому в format нужно передавать не весь buf, а только часть данных длинной равной count.
ну вот вроде предусмотрел последнее чтение файла

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace client
{
    class Program
    {
        public static void Main(string[] args)
        {
            TcpClient eclient = new TcpClient("localhost",34567);
            NetworkStream writerStream = eclient.GetStream();
            BinaryFormatter format = new BinaryFormatter();
            byte[] buf = new byte[1024 ];
            int count;
            FileStream fs = new FileStream("111.txt", FileMode.Open);
            BinaryReader br = new BinaryReader(fs);
            long lengthFile = fs.Length;//Размер файла.
            format.Serialize(writerStream, lengthFile.ToString());//Вначале передаём размер
            
            // определяем сколько надо считывать байтов что бы ровно закончить в конце файла
            long howMuch = lengthFile - 1024;
            lengthFile -= 1024; // что бы смотреть сколько осталось байтов для передачи
            if (howMuch < 0)
                howMuch = 1024 + howMuch; // получается по знакам 1024 - howMuch
            while ((count = br.Read(buf, 0, (int)howMuch )) > 0)
            {
                format.Serialize(writerStream, buf); // ТУТ ЖЕ УЖЕ НЕ ПО 1024 ПЕРЕДАЕМ, А ВСЕ РАВНО БЕДА
                // надо ли дальше считывать
                if (lengthFile>0)
                {
                    howMuch = lengthFile - 1024;
                    lengthFile -= 1024;
                    if (howMuch < 0)
                        howMuch = 1024 + howMuch;
                }
                else
                    howMuch = 0;
                
            }
 
            
            
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}
Добавлено через 27 минут
Все, спасибо. я разобрался. и без сериализации
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
08.04.2010, 02:50
Цитата Сообщение от borN_free Посмотреть сообщение
Все, спасибо. я разобрался. и без сериализации
Ну тогда делитесь кодом. Потомкам на радость
0
3 / 3 / 0
Регистрация: 18.03.2010
Сообщений: 5
08.04.2010, 03:18
Учитывая советы толковых людей сделал передачу файла так:

Клиент:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TcpClient eclient = new TcpClient("localhost",34567);
NetworkStream writerStream = eclient.GetStream();
byte[] buf = File.ReadAllBytes("111.wmv");
 
// посылаем размер файла
long lengthFile = buf.Length;
StreamWriter sw = new StreamWriter(writerStream);
sw.WriteLine(lengthFile.ToString());
sw.Flush();
 
// посылаем сам файл
writerStream.Write(buf, 0 , buf.Length);
writerStream.Flush();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Сервер:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpListener clientListener = new TcpListener(ip, 34567);
clientListener.Start();
TcpClient client = clientListener.AcceptTcpClient();
NetworkStream readerStream = client.GetStream();
 
// считываем размер файла
StreamReader sr = new StreamReader(readerStream);
string s = sr.ReadLine();
int length= Convert.ToInt32(s);
 
byte[] buf = new byte[length];
readerStream.Read(buf, 0, length);
 
File.WriteAllBytes("222111.wmv", buf);
 
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Не откажусь от критики, но мне кажется так удобней передавать, чем предлагалось выше. Единсвтенное меня смущает отправка/принятие размера файла, можете подкорректировать
2
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
09.04.2010, 04:20
Цитата Сообщение от borN_free Посмотреть сообщение
string s = sr.ReadLine();
int length= Convert.ToInt32(s);
Для длины файла можно использовать Int. Тогда можно облегчить запись и чтение заголовка о размере.
C#
1
int length = sr.Read();
В качестве доп. функционала, можно добавить запись в поток имени файла. Тогда клиент может сохранить файл с оригинальным названием.
0
3 / 3 / 0
Регистрация: 18.03.2010
Сообщений: 5
10.04.2010, 11:19
Вобщем еще один вариант для критики.
отправляем
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
byte[] buf = File.ReadAllBytes(pathAndName[0]); // полный путь файла
 
// посылаем размер файла
long lengthFile = buf.Length;
writerStream.Write(BitConverter.GetBytes(lengthFile), 0, 8);
writerStream.Flush();
 
// посылаем имя файла
long name_length = Encoding.Unicode.GetBytes(pathAndName[1]).Length;
byte[] name_buf = new byte[name_length];
// сначала посылаем длину строки
writerStream.Write(BitConverter.GetBytes(name_length), 0, 8);
// теперь саму строку имени файла
name_buf = Encoding.Unicode.GetBytes(pathAndName[1]);
writerStream.Write(name_buf, 0, (int)name_length);
 
// посылаем сам файл
writerStream.Write(buf, 0 , buf.Length);
writerStream.Flush();
принимаем
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// считываем размер файла
long length= 0;
byte[] b = new byte[8]; // хранит длину в байтах
readerStream.Read(b, 0, 8);
length = BitConverter.ToInt64(b, 0);
 
// считываем имя файла
// сначала длину строки считываем
long name_length = 0;
byte[] bl = new byte[8];
readerStream.Read(bl, 0, 8);
name_length = BitConverter.ToInt64(bl, 0);
byte[] name_buf = new byte[name_length];
readerStream.Read(name_buf, 0, (int)name_length);
string name_file = Encoding.Unicode.GetString(name_buf);
this.Invoke(new dgUpdateLabel(this.UpdateLog), new object[] { name_file});
 
byte[] buf = new byte[length];
readerStream.Read(buf, 0, (int)length);
 
 
File.WriteAllBytes(".\\"+name_file, buf);
Данный код локально работает нормально, НО при передачи по сети - передаваемые файлы не открываются (кроме текстовых), хотя количество байт одинаково в источнике и копии. Не могу понять причину.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.04.2010, 11:19

Передача нескольких файлов через TCP одновременно
Как передавать несколько файлов через TCP одновременно, я пока что вижу только один вариант передавать их по очереди, есть ли какой нибудь...

TCP передача файлов
Здравствуйте, разбирался в структуре и способе работы с протоколом по передачи данных TCP, сделал сервер на С++ (Linux) так же есть клиент...

Передача больших файлов tcp. Клиент зависает
Здравствуйте, мне нужно было написать два приложения клиент (c#) и сервер(c++ под linux) и организовать передачу файлов между ними. ...

TCP Клиент-Сервер, передача файлов, упрощение кода
TCP Клиент Сервер передача файлов упрощение Вот стартовый пример передачи файлов , я нашкрябал Раклями своими :D от клиента серверу ...

Очень интерестный вопрос
Умные люди подскажите пожайлуста как с SQL хранимой процедуры вызвать отправку почту sql -ую. Т.е. не CDO-ную а именно SQL


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru