Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/25: Рейтинг темы: голосов - 25, средняя оценка - 4.76
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486

Передача содержимого от сервера клиенту или наоборот через TCP

20.11.2018, 03:19. Показов 5112. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вопрос на засыпку.
Есть сервер который должен например передать фотографию клиенту или какой то огромный текст, мы знаем что можно передать только байтами содержимое и мы знаем что есть максимальное количество байт которое можно передать по каналу оно 1500 байт. Вопрос такой когда я посылаю например фотографию целиком не разбивая массив байтов таким образом

C#
1
2
3
4
5
6
7
8
9
10
11
using (Bitmap bitmap = new Bitmap(1800,1000))
{
        Size s = new Size(bitmap.Width, bitmap.Height);
        using (Graphics g = Graphics.FromImage(bitmap))
        {
               g.CopyFromScreen(0, 0, 0, 0, s);
        }
 
        byte[] data = (byte[])TypeDescriptor.GetConverter(bitmap).ConvertTo(bitmap, typeof(byte[]));
        socket.Send(data,0,data.Length,SocketFlags.None); //фотография в данном случае 175000 байт
}
где socket.Send он сам может разбивать массив или же всё таки надо разбивать массив?
заранее спасибо!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.11.2018, 03:19
Ответы с готовыми решениями:

Передача сообщения с сервера клиенту
Здравствуйте! Я только начинающий программист, пишу програмку для интернет клуба. И вот у меня два вопроса: 1) Подскажыте как можно на...

Как отправить byte[] с сервера клиенту через socket
Как отправить byte с сервера клиенту через socket? Я могу отправить с клиента на сервер вот так. Клиент: string ipadr =...

Передача изображения от сервера к клиенту
Сервер: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; ...

20
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,929
20.11.2018, 06:17
Цитата Сообщение от FerrariF70 Посмотреть сообщение
мы знаем что есть максимальное количество байт которое можно передать по каналу оно 1500 байт.
Это в LAN. Размер пакета (MTU) зависит от природы сети и настроек сетевого оборудования.

Цитата Сообщение от FerrariF70 Посмотреть сообщение
socket.Send он сам может разбивать массив или же всё таки надо разбивать массив?
Протокол TCP сам всё за вас сделает. Просто предоставьте буфер с данными и всё.
0
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
20.11.2018, 08:44  [ТС]
Т.е в моём случае код делает снимок экран соответственно конвертирую в байтовый массив. И просто отправляю через socket.Send() там работу дальше уже TCP делает? Потому что я например с текстом задолбался разбивать он муссор типа такого \0\0 гонит в строку
И сэтим ничего не возможно сделать.
А где можно прочитать про то как в c# байты разбиваются на пакеты? Заранее спасибо!
0
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,929
20.11.2018, 10:53
Лучший ответ Сообщение было отмечено FerrariF70 как решение

Решение

Цитата Сообщение от FerrariF70 Посмотреть сообщение
И просто отправляю через socket.Send() там работу дальше уже TCP делает?
Да.

Цитата Сообщение от FerrariF70 Посмотреть сообщение
Потому что я например с текстом задолбался разбивать он муссор типа такого \0\0 гонит в строку
И сэтим ничего не возможно сделать.
Это исключительно проблемы вашего кода. Ведь возвращаемое методом Socket.Receive значение реально прочитанных байт вы не проверяете и не учитываете, так ведь?

Добавлено через 1 минуту
Цитата Сообщение от FerrariF70 Посмотреть сообщение
А где можно прочитать про то как в c# байты разбиваются на пакеты? Заранее спасибо!
Если речь о сокетах, то C# тут вообще не причём. Socket - обёртка над API операционной системы, которая реализует стандартный протокол, который одинаково работает что в линуксе на С++, что в макоси на питоне.
1
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
20.11.2018, 19:29  [ТС]
Usaga
насчёт Socket.Receive() мусор начал появляться в сообщениях потому что я на стороне сервера разбивал массив байтов на пакеты и отправлял их а на стороне клиента я их собирал обратно в байтовый массива. Но перед тем как я начал разбивать просто посылал буффер

таким образом на сервере посылаю:
C#
1
 socket.Send(ascii.GetBytes("Hello World!"));
и таким образом на клиенте принимаю то нет никакого мусора:

C#
1
2
3
int k = socket.Receive(BinDataIn, 0, 50, SocketFlags.None);
 detail = ascii.GetString(BinDataIn, 0, k);
 Console.WriteLine(detail);
разбиваю я таким образом на сервере чего делать я так понимаю не стоит:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 using (Bitmap bitmap = new Bitmap(1800,1000))
                {
                    Size s = new Size(bitmap.Width, bitmap.Height);
                    using (Graphics g = Graphics.FromImage(bitmap))
                    {
                        g.CopyFromScreen(0, 0, 0, 0, s);
                    }
 
                    byte[] data = (byte[])TypeDescriptor.GetConverter(bitmap).ConvertTo(bitmap, typeof(byte[]));
                    byte[] buffer = new byte[1024];
 
 
                    socket.Send(ascii.GetBytes(data.Length.ToString()));
                    int readIndex = 0;
                    while (readIndex < data.Length)
                    {
                        int offset = (data.Length - readIndex < 1024) ? data.Length - readIndex : buffer.Length;
                        Buffer.BlockCopy(data, readIndex, buffer, 0, offset);
                        socket.Send(buffer,0,buffer.Length,SocketFlags.None);
                        readIndex += buffer.Length;
                    }
                }
и на клиенте я собираю пакеты от сервера таким образом:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public static void GetQueryFromServer()
        {
            int offset = 0, indexRead = 0;
            while (indexRead < buffDataIn.Length)
            {
                k = socket.Receive(BinDataIn, 0, 1024, SocketFlags.None);
                offset = (buffDataIn.Length - indexRead < 1024) ? buffDataIn.Length - indexRead : 1024;
                Buffer.BlockCopy(BinDataIn, 0, buffDataIn, indexRead, offset);
                indexRead += 1024;
            }
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(ascii.GetString(buffDataIn, 0, buffDataIn.Length));
            Console.ResetColor();
        }
Добавлено через 9 минут
мусор как таковой не виден в консоле только если через отладчик он виден но всё равно это создаёт много проблем.
0
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,929
21.11.2018, 06:59
Лучший ответ Сообщение было отмечено FerrariF70 как решение

Решение

Цитата Сообщение от FerrariF70 Посмотреть сообщение
разбиваю я таким образом на сервере чего делать я так понимаю не стоит:
Ужас. Зачем вам TypeDescriptor.GetConverter(bitmap).ConvertTo, если у Bitmap есть метод Save?

На буферы разбивают не для того, чтобы TCP облегчить передачу данных, а для того, чтобы не пихать в оперативку заведомо конское количество данных. В вашем случае, рисунок уже в оперативке и буфер с его содержимым можно сразу передать методу Socket.Send. Но если бы рисунок поднимался с диска, то разумнее было бы читать его порциями по N килобайт, чтобы не захламлять память.

Вот это вообще бомба: socket.Send(ascii.GetBytes(data.Length.ToString()));.
1
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
22.11.2018, 09:01  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Ужас. Зачем вам TypeDescriptor.GetConverter(bitmap).Conv ertTo, если у Bitmap есть метод Save?
я пока что учусь, насчёт Bitmap и его метода Save как то не задумывался спасибо что подсказали
Цитата Сообщение от Usaga Посмотреть сообщение
socket.Send(ascii.GetBytes(data.Length.T oString()));
это просто тестирую
0
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
22.11.2018, 23:26  [ТС]
Usaga возможно ли как то вообще уведомить клиента какой размер байтов я ему отсылаю?
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
23.11.2018, 00:16
Цитата Сообщение от FerrariF70 Посмотреть сообщение
возможно ли как то вообще уведомить клиента какой размер байтов я ему отсылаю?
Ну так в самом начале и передайте.
Вы передаете длину пакета, например int - 4 байта.
Клиент читает первые 4 байта, преобразует в int. И далее читает нужно число байт из сокета.
1
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
23.11.2018, 02:48  [ТС]
Storm23, понятно и тут мы вернулись к началу как я и вначале разбивал на пакеты.Спасибо!
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
23.11.2018, 02:55
Цитата Сообщение от FerrariF70 Посмотреть сообщение
понятно и тут мы вернулись к началу как я и вначале разбивал на пакеты.Спасибо!
Да не нужно разбивать на пакеты. Отправляйте одним пакетом. Просто в начале нужно отправить длину этого пакета. Что бы клиент знал сколько данных ему ожидать.
И да, в этом контексте пакет это не тоже самое что пакет TCP. Пакеты на которые разобьет TCP вас вообще не должно волновать. В данном контексте пакет - это просто блок передаваемых данных, который клиент должен принять целиком, перед началом обработки.
0
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
23.11.2018, 03:00  [ТС]
C#
1
Send(ascii.GetBytes(data.Length.ToString()));
значит такой вариант будет отличный как я в начале в коде прописал?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
23.11.2018, 03:07
Цитата Сообщение от FerrariF70 Посмотреть сообщение
значит такой вариант будет отличный как я в начале в коде прописал?
Нет.

C#
1
Send(BitConverter.GetBytes(data.Length));
0
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
23.11.2018, 19:06  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Send(BitConverter.GetBytes(data.Length)) ;
К сожалению ваше решение выводит не то что предполагается. ответ на стороне клиента таков: u0004 я даже не знаю что под этим предполагается, смотрел если это что то из юникода но и там не нашёл ничего.
моё решение сработало отлично

C#
1
2
ASCIIEncoding ascii = new ASCIIEncoding();
socket.Send(ascii.GetBytes(data.Length.ToString()));
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
23.11.2018, 20:07
Цитата Сообщение от FerrariF70 Посмотреть сообщение
К сожалению ваше решение выводит не то что предполагается. ответ на стороне клиента таков: u0004 я даже не знаю что под этим предполагается, смотрел если это что то из юникода но и там не нашёл ничего.
моё решение сработало отлично
Потому что вы неправильно делаете.
0
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
23.11.2018, 20:10  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Потому что вы неправильно делаете.
в смысле не правильно? по вашему рецепту делал. если у меня что то не правильно вышло то и в вашем примере вы не правильно прописали
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
23.11.2018, 20:12
Я написал как отправлять. А вы на клиенте не правильно делаете (число зачем-то в строку переводите...), про это я ничего не писал...
0
17 / 14 / 7
Регистрация: 04.02.2017
Сообщений: 486
23.11.2018, 20:19  [ТС]
C#
1
2
k = socket.Receive(DataIn,0,256,SocketFlags.None);
            msg = ascii.GetString(DataIn, 0, k);
на клиенте я принимаю таким образом, что тут не правильно?

я уже написал что я делал вашим способом и он бред выдавал вы хотите скрин чтоб убедится или что?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
23.11.2018, 20:49
Цитата Сообщение от FerrariF70 Посмотреть сообщение
на клиенте я принимаю таким образом, что тут не правильно?
Все неправильно.
C#
1
2
3
4
5
byte[] buf = new byte[4];
int received = sock.Receive(buf, 0, buf.Length, SocketFlags.None);
if (received != buf.Length)
    throw new Exception("houston we have a problem"); // тут нужно обработать ситуацию если пришло меньше 4 байт...
int dataLength = BitConverter.ToInt32(buf, 0);

Цитата Сообщение от FerrariF70 Посмотреть сообщение
я уже написал что я делал вашим способом и он бред выдавал вы хотите скрин чтоб убедится или что?
Потому что неправильно делали...

И вообще проще было бы использовать TcpClient/TcpListener/NetworkStream/BinaryReader/BinaryWriter чем мудохаться с этим сокетом и вручную разбирать пакеты...
0
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,929
24.11.2018, 06:37
FerrariF70, я вам тоже не рекомендую использовать голый TCP раз уж вы с трудом понимаете, что делаете. Это довольно низкоуровневая штука. Вот тут разбираются правильные практики работы с TCP. В самом конце статьи есть полный пример корректной работы с TCP, учитывающий фрагментирование пакетов и прочие вещи. Обратите внимание, что этот пример вообще ниразу не так прост.

Если вы использовали TCP не потому, что вам нужна вся эта низкоуровневая мишура, а просто потому, что это первое, что вам попалось, то возьмите что-то другое. Что-то из надстроек, что выше Someone007 порекомендовал. Или ещё более высокоуровневые вещи типа WCF.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.11.2018, 06:37
Помогаю со студенческими работами здесь

Передача ошибки из библиотеки DAL со стороны сервера к клиенту
Добрый день всем! Задался вопросом, как можно пробросить ошибку со стороны сервера к клиенту? На стороне сервера есть библиотека DAL,...

Передача динамических данных с сервера на клиент по TCP/IP
Как только не гуглил, никак не могу найти пример реализации или что-то в этом роде. Требуется написать простенькое клиент-серверное...

Как отправить ответ клиенту с сервера TCP?
Посмотрите пожалуйста эти Клиент и Сервер. Я отправляю команду серверу с просьбой отправить данному клиенту файл, но как передать экземпляр...

ApiController передача изображений от сервера клиенту
Добрый день, уважаемые коллеги. Прошу помочь советом. Требуется реализовать API с передачей изображения от сервера клиенту. ...

Передача данных из сервера к клиенту или наоборот
Всем привет. В общем проблема такова: Есть скрипт, который создаёт персонажей по клику мыши и по позиции курсора. Но дело в том, что я...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru