Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
19 / 15 / 6
Регистрация: 14.07.2021
Сообщений: 47
.NET 5

Как правильно использовать метод SendFile класса Socket?

24.07.2021, 10:26. Показов 3917. Ответов 3

Студворк — интернет-сервис помощи студентам
Здравствуйте. Передо мной стоит задача отправки файлов (видео) на удалённый адрес. Почитав документацию я увидел, что в классе Socket присутствует метод SendFile: https://docs.microsoft.com/ru-... ew=net-5.0

Но, когда смотрел листинги программ других людей, там этот метод не используют, а по старинке отправляют файл при помощи байтового массива. Скажите пожалуйста, есть ли в этом методе какой-то подвох и почему его редко используют? Мне нужно отправлять файлы достаточно большого объёма (несколько сотен мегабайт) по TCP. На данный момент я использую этот метод примерно вот так:
C#
1
2
3
4
5
6
7
8
9
10
11
try
                {
                    _server.Connect(endPoint);
                    _server.SendFile(filePath);
                    _server.Close();
                    ConsoleMessenger.WriteSuccess($"{filePath} успешно отправлен на сервер");
                }
                catch (NotSupportedException ex) { ConsoleMessenger.WriteError(ex.Message); }
                catch (InvalidOperationException ex) { ConsoleMessenger.WriteError(ex.Message); }
                catch (FileNotFoundException ex) { ConsoleMessenger.WriteError(ex.Message); }
                catch (SocketException ex) { ConsoleMessenger.WriteError(ex.Message); }
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.07.2021, 10:26
Ответы с готовыми решениями:

Отправка файла методом socket.SendFile
Здравствуйте, отправляю файл по локальной сети методом socket.SendFile, файлы размером ~1.5 гб отправляет, когда пытаюсь отправить файл на...

Socket.SendFile - не получается заголовки добавить
Есть сервер http, к нему подключается клиент, которому нужно дать изображение вместе с заголовками. Как это выглядит в сниффере - ...

Как правильно вызвать метод класса внутри самого класса?
Здравствуйте. Собственно тема прописана в заголовке: как правильно вызвать метод класса внутри самого класса? Насколько я знаю, для...

3
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
24.07.2021, 12:13
Лучший ответ Сообщение было отмечено Vollane как решение

Решение

скорее всего, но это не точно, проблема в 4кб кеше при чтении файла в этом методе, когда ты вычитываешь файл в ручную то кеш для чтения файла можно поставить и 1MB и 10 MB и 100MB, как ты понимаешь чем быстрее ты вайл вычитаешь тем быстрее ты его отправишь
0
19 / 15 / 6
Регистрация: 14.07.2021
Сообщений: 47
24.07.2021, 12:21  [ТС]
агерон, то есть, всё же предпочтительнее не использовать этот метод?
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
25.07.2021, 00:50
Цитата Сообщение от Vollane Посмотреть сообщение
Мне нужно отправлять файлы достаточно большого объёма (несколько сотен мегабайт) по TCP.
Stream в помощь. Если нужно оставить возможность паралельно "вклинить" дополнительные пакеты других сообщений/файлов, то тут нужно уже продумать архитектуру "протокола". Я бы сказал "не знаю каких вы людей смотрите, что не наткнулись на это очевидное решение", но реальность такова что конкретно для Socket примеры почему-то всегда сводятся к передачи долбаного текста.

Добавлено через 2 часа 31 минуту
Мини пример, как можно "залить" файл используя потоки. Естественно все это блокирующее выполнение в том плане что пока "заливается" файл, паралельно ничего отправлять не получится (async-await тут по другим причинам и от этой проблемы не спасают, т.к. это скорее вопрос логической организации Stream).

Еще глянул что вообще творит метод SendFile -- вроде он тоже просто "льет" файл в поток, но при попытке подсунуть 2.75Гб вываливается с System.Net.Sockets.SocketException: 'The parameter is incorrect.' Учитывая что в документации не шибко упоминаются какие-то ограничения, возможно даже внутренний баг. Да и в целом это блокирующий метод, в современном мире с асинхронным подходом... Даже не знаю, я бы использовал его разве что для отправки чего-то мелкого, чтобы написать максимально просто и компактно.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace Nya.CyberForum.ExampleSendFile
{
    class Program
    {
        static void Main(string[] args)
        {
            var ip = "127.0.0.1";
            var port = 39033;
 
            var server = new Server(ip, port, @"D:\Temp\ExampleSendFile\");
            server.Start();
            var client = new Client();
            client.UploadAsync(ip, port, @"D:\Overlay\Genshin Impact\Desktop 2021.05.12 - 22.46.32.02.mp4")
                .Wait();
            client.Upload(ip, port, @"D:\Overlay\Genshin Impact\Genshin Impact 2021.07.18 - 03.13.31.01.mp4");
            Console.ReadKey();
            server.Stop();
            Console.ReadKey();
        }
    }
 
    public class Client
    {
        public async Task UploadAsync(string ip, int port, string file)
        {
            using var client = new TcpClient();
            await client.ConnectAsync(IPAddress.Parse(ip), port);
            using var writer = client.GetStream();
            using var binaryWriter = new BinaryWriter(writer, Encoding.UTF8);
            binaryWriter.Write(Path.GetFileName(file));
            using var reader = new FileStream(file, FileMode.Open);
            await reader.CopyToAsync(writer);
        }
 
        public void Upload(string ip, int port, string file)
        {
            using var client = new TcpClient();
            client.Connect(IPAddress.Parse(ip), port);
            using var writer = client.GetStream();
            using var binaryWriter = new BinaryWriter(writer, Encoding.UTF8);
            binaryWriter.Write(Path.GetFileName(file));
            client.Client.SendFile(file);
        }
    }
 
    public class Server 
    {
        private readonly IPEndPoint _endPoint;
        private readonly string _path;
        private TcpListener listener;
        private CancellationTokenSource cancelationSource;
        private Task running;
 
        public Server(string ip, int port, string path)
        {
            _endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
            _path = path;
        }
 
        public void Start()
        {
            listener = new TcpListener(_endPoint);
            listener.Start();
            cancelationSource = new CancellationTokenSource();
            running = WaitConnection(cancelationSource.Token);
        }
 
        public void Stop()
        {
            cancelationSource.Cancel();
            listener.Stop();
            running.Wait();
            Console.WriteLine("server stoped");
        }
 
        private async Task WaitConnection(CancellationToken cancellation)
        {
            while (!cancellation.IsCancellationRequested)
            {
                try
                {
                    var newConnection = await listener.AcceptTcpClientAsync();
                    var readTask = Task.Run(async () => await ReadFile(newConnection, cancellation), cancellation);
                    //в идеале нужно запоминать все readTask и на Stop дожидатся их окончания
                }
                catch (Exception ex)
                {
                    //проверка что не свалились по Stop
                    if((ex as SocketException)?.SocketErrorCode != SocketError.OperationAborted)
                        Console.WriteLine(ex);
                }
            }
 
        }
 
        private async Task ReadFile(TcpClient client, CancellationToken cancellation)
        {
            using (client)
            { 
                using var reader = client.GetStream();
                using var binaryReader = new BinaryReader(reader, Encoding.UTF8);
                var filename = binaryReader.ReadString();
                using var writer = new FileStream(Path.Combine(_path, filename), FileMode.Create);
                await reader.CopyToAsync(writer, cancellation);
                Console.WriteLine($"file {filename} uploaded");
            }
        }
    }
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.07.2021, 00:50
Помогаю со студенческими работами здесь

Как использовать метод класса
Хорошего всем дня Есть одна задачка, не могу понять как использовать метод класса Cat public void sayMeow() в классе ...

Как правильно использовать метод post?
Помогите разобраться как правильно использовать метод post в запросах для записи информации в базу данных. В программе использую...

Как правильно использовать нестатические методы класса
здраствуйте. у меня можно так сказать этический вопрос, по поводу использования нестатических методов классов в c#:) я часто использую...

метод класса,как использовать его
в классе есть функция как ее вызвать из главной функции?

Как использовать метод Summ из класса Fraction?
Всем привет! Есть задача сделать калькулятор дробей в Windows Form. В два текстбокса забиваются числитель и знаменатель первой дроби, в...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru