Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
0 / 0 / 1
Регистрация: 09.11.2013
Сообщений: 26

Передача больших сообщений

22.11.2014, 03:13. Показов 2696. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблема состоит в том что сервер принимает структуру в структуре есть поле char a[20][97]; оно передается нормально некоторое время, а потом передается черте что. Поле на клиенте не изменяю оно статично(для проверки делал) в чем может быть проблема
C++
1
send(my_sock2, (char*)&d11, sizeof(d11), 0);
структуру передаю так
C++
1
            bytes_recv1 = recv(my_sock1, (char*)&d1, sizeof(d1), 0);
принимаю так сама структура.

C++
1
2
3
4
5
6
7
8
9
10
11
typedef struct {
float x;
float y;
char TileMap[20][97];
 
} Data;
 
Data d1;
    Data d2;
    Data d11;
    Data d22;
Добавлено через 2 часа 50 минут
Передаю я сообщение 2 кб....
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.11.2014, 03:13
Ответы с готовыми решениями:

Передача сообщений через pipe
Прошу помочь с реализацией курсового проекта. Я очень плохо шарю в c++, поэтому ничего не могу понять( Нужно через pipe реализовать...

Передача сообщений между клиентами
Всем привет! Пытаюсь написать программу для передачи сообщений между клиентами (пример взят из статьи "Самоучитель игры на...

Передача больших файлов по TCP
Здравствуйте! При передаче небольших файлов вопросов не возникает. Теперь стала задача передать файл размером скажем 64 мБ если в send...

28
Native x86
Эксперт Hardware
 Аватар для quwy
6856 / 3789 / 1025
Регистрация: 13.02.2013
Сообщений: 11,861
22.11.2014, 03:24
Fueled9456, хоть и на примере Delphi, но касается всех: О правильном использовании TServerSocket/TClientSocked и подобными компонентами (у вас скорее всего проблема, описанная в пунктах 2, 3 ,4).
0
0 / 0 / 1
Регистрация: 09.11.2013
Сообщений: 26
22.11.2014, 12:30  [ТС]
Эти проблемы должны решать 7 уровней модели OSI. К сабжу у меня 2 клиента обслуживаються в одном потоке!
0
Native x86
Эксперт Hardware
 Аватар для quwy
6856 / 3789 / 1025
Регистрация: 13.02.2013
Сообщений: 11,861
22.11.2014, 22:25
Цитата Сообщение от Fueled9456 Посмотреть сообщение
Эти проблемы должны решать 7 уровней модели OSI
Кто вам это сказал? Стек TCP/IP гарантирует только последовательность доставки пакетов, а не их атомарность. Порезаться может даже двухбайтовый пакет, слипнуться -- даже килобайтные.

Цитата Сообщение от Fueled9456 Посмотреть сообщение
у меня 2 клиента обслуживаються в одном потоке!
потоки к проблеме доставки пакетов отношения не имеют, но в случае кривого кода могут привести и к вашим симптомам.
1
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
24.11.2014, 18:10
Fueled9456, ты попечатай размер посылаемой структуры и сколько recv приняла. И погоняй. Циферки сойдуться?
1
3 / 3 / 3
Регистрация: 28.03.2013
Сообщений: 45
27.11.2014, 22:54
Fueled9456, поставь задержку в 200мс перед каждой отправкой. если будет нормально можно немного уменьшить.
0
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
29.11.2014, 09:57
Передавай пакеты размером не больше MTU.

Цитата Сообщение от quwy Посмотреть сообщение
Порезаться может даже двухбайтовый пакет,
Нет не порежется, а вот 2 двухбайтовых пакета слипнуться в одном.

Ну еще один момент, почувствуй разницу, структуры абсолютно одинаковые в плане описания, но размер их разный.

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
struct Struct1
{
    unsigned char a;
    char b;
    short c;
    int d;
    unsigned char e;
};
 
#pragma pack (push, 1)
struct Struct2
{
    unsigned char a;
    char b;
    short c;
    int d;
    unsigned char e;
};
#pragma pack (pop)
 
int main()
{
    printf("Struct1 = %i\n", sizeof(Struct1));
    printf("Struct2 = %i\n", sizeof(Struct2));
}
0
0 / 0 / 1
Регистрация: 09.11.2013
Сообщений: 26
30.11.2014, 16:15  [ТС]
по другому ни как я не смогу передавать сообщения без потери? а как определить что сообщение целое при приеме
0
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
30.11.2014, 16:20
Цитата Сообщение от Fueled9456 Посмотреть сообщение
а как определить что сообщение целое при приеме
Ну хотя бы обрамить в свой протокол обмена
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
01.12.2014, 01:37
Цитата Сообщение от Fueled9456 Посмотреть сообщение
по другому ни как я не смогу передавать сообщения без потери?
Что значит потери ? recv за раз читает некоторое количество байт, меньшее,
либо равное размеру принимающего буфера. Сколько именно байт будет принято -
неизвестно, любые предположения относительно этого количества - ошибочны.

Если вы обмениваетесь данными по определенному протоколу, построенному поверх TCP,
например HTTP, и знаете, что конец сообщения еще не достигнут, зовите recv еще и еще,
пока все ожидаемые данные не будут приняты.

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

quwy и Andrej выше все по делу написали.
TCP - это просто поток данных, и работать с ним нужно, как с потоком, а
не как с набором сообщений или пакетов.
0
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
01.12.2014, 05:16
Цитата Сообщение от Убежденный Посмотреть сообщение
TCP - это просто поток данных
Нет это протокол гарантированной доставки сообщений, но он не гарантирует что за одно чтение примется столько же байт сколько было и отправлено, за одно чтение может быть получено больше или меньше байт. За одно чтение может быть считано две отправленные порции байт или половина порции отправленных байт.
0
3 / 3 / 3
Регистрация: 28.03.2013
Сообщений: 45
01.12.2014, 10:32
То что TCP это поток данных это правильно и то что гарантирует доставку тоже правильно. НО если ты будешь несколько подрят отправлять сообщение допустим три раза. то ты можешь получить не три сообщения а два. У тебя в первом сообщение будет налеплено и первое и второе отправленное сообщение, а во втором третье отправленное сообщение. А может что в первом принятом получишь первое отправленное, а во втором третье отправленное. Дело в том что данные у тебя не успевают отсылатся как ты уже новые пытаешься отослать. Вот то что не успело отослатся затирается новыми данными. И вообще данные что отослал они приходят не сразу одной отправкой. Если отправляешь большой файл то он частями отправляет данные.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
01.12.2014, 12:00
Цитата Сообщение от demmax2004 Посмотреть сообщение
но он не гарантирует что за одно чтение примется столько же байт сколько было и отправлено, за одно чтение может быть получено больше или меньше байт.
Я именно об этом и толкую.

Цитата Сообщение от angoli Посмотреть сообщение
НО если ты будешь несколько подрят отправлять сообщение допустим три раза. то ты можешь получить не три сообщения а два. У тебя в первом сообщение будет налеплено и первое и второе отправленное сообщение, а во втором третье отправленное сообщение.
Да, такое вполне может быть.

Цитата Сообщение от angoli Посмотреть сообщение
А может что в первом принятом получишь первое отправленное, а во втором третье отправленное.
А вот такого в TCP быть не может, потому что нарушается гарантия доставки.
Или это не TCP вообще никакой.

Цитата Сообщение от angoli Посмотреть сообщение
Дело в том что данные у тебя не успевают отсылатся как ты уже новые пытаешься отослать. Вот то что не успело отослатся затирается новыми данными.
Не может такого быть в TCP. Никак.
0
3 / 3 / 3
Регистрация: 28.03.2013
Сообщений: 45
01.12.2014, 12:30
А вот такого в TCP быть не может, потому что нарушается гарантия доставки.
Или это не TCP вообще никакой.
Поверь может быть. Использовал CSocket и указывал при создания сокета SOCK_STREAM, что означает использование TCP. Я делал локальный проводник и когда я получал список папок на диске, то вместо примерно 10-15 я получал лишь 3-4. Вопрос куда делись остальные? Но когда я сделал задержку перед каждой отправки данных папок я получал весь список. Вот и ответ напрашивается сам. Что данные затираются. Т.е. если сервер отправил первую строку, а у него уже в очереди вторая и третья строка, то он отправляет третью.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
01.12.2014, 13:51
Цитата Сообщение от angoli Посмотреть сообщение
Поверь может быть.
Не поверю.

Цитата Сообщение от angoli Посмотреть сообщение
Использовал CSocket и указывал при создания сокета SOCK_STREAM, что означает использование TCP. Я делал локальный проводник и когда я получал список папок на диске, то вместо примерно 10-15 я получал лишь 3-4. Вопрос куда делись остальные?
А ты уверен, что твой клиент-сервер был написан корректно ?

Цитата Сообщение от angoli Посмотреть сообщение
Вот и ответ напрашивается сам. Что данные затираются.
Старые данные, которые еще не были отправлены, не могут затираться новыми.
Это противоречит концепции TCP-стека, в частности, это нарушает гарантию порядка
доставки, и не только.

Цитата Сообщение от angoli Посмотреть сообщение
Т.е. если сервер отправил первую строку, а у него уже в очереди вторая и третья строка, то он отправляет третью.
Извини, но это полная чушь.
Очередь TCP - она на то и очередь, чтобы отправлять данные последовательно, один за другим,
чтобы они прибыли в пункт назначения в точности в таком же составе и порядке.
Если эта схема доставки нарушается, тогда одно из трех: либо аппаратная ошибка где-нибудь
на линии (такое бывает, но очень-очень редко, один случай на миллиарды), либо это вообще
не протокол TCP, либо реализация клиент-сервера некорректная. Я склоняюсь к третьему варианту.

Вот выдержки из спецификации TCP (RFC 793), ключевые моменты выделены жирным:
https://www.ietf.org/rfc/rfc793.txt
Reliability:

The TCP must recover from data that is damaged, lost, duplicated, or
delivered out of order by the internet communication system. This
is achieved by assigning a sequence number to each octet
transmitted, and requiring a positive acknowledgment (ACK) from the
receiving TCP. If the ACK is not received within a timeout
interval, the data is retransmitted. At the receiver, the sequence
numbers are used to correctly order segments that may be received
out of order and to eliminate duplicates. Damage is handled by
adding a checksum to each segment transmitted, checking it at the
receiver, and discarding damaged segments.


As long as the TCPs continue to function properly and the internet
system does not become completely partitioned, no transmission
errors will affect the correct delivery of data. TCP recovers from
internet communication system errors.

...

2.6. Reliable Communication

A stream of data sent on a TCP connection is delivered reliably and in
order at the destination.

Transmission is made reliable via the use of sequence numbers and
acknowledgments. Conceptually, each octet of data is assigned a
sequence number. The sequence number of the first octet of data in a
segment is transmitted with that segment and is called the segment
sequence number. Segments also carry an acknowledgment number which
is the sequence number of the next expected data octet of
transmissions in the reverse direction. When the TCP transmits a
segment containing data, it puts a copy on a retransmission queue and
starts a timer; when the acknowledgment for that data is received, the
segment is deleted from the queue. If the acknowledgment is not
received before the timer runs out, the segment is retransmitted.


...

Send

In the simplest implementation, SEND would not return control to
the sending process until either the transmission was complete
or the timeout had been exceeded. However, this simple method
is both subject to deadlocks (for example, both sides of the
connection might try to do SENDs before doing any RECEIVEs) and
offers poor performance, so it is not recommended. A more
sophisticated implementation would return immediately to allow
the process to run concurrently with network I/O, and,
furthermore, to allow multiple SENDs to be in progress.
Multiple SENDs are served in first come, first served order, so
the TCP will queue those it cannot service immediately.


...

Receive

To distinguish among several outstanding RECEIVEs and to take
care of the case that a buffer is not completely filled, the
return code is accompanied by both a buffer pointer and a byte
count indicating the actual length of the data received.
0
3 / 3 / 3
Регистрация: 28.03.2013
Сообщений: 45
01.12.2014, 15:02
Мой кусок кода сервера.

kyrs4ServerDlg.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
 
BOOL Ckyrs4ServerDlg::OnInitDialog()
{
...
 
BOOL bRet;
    bRet = m_ListenSocket.Create( 2000, SOCK_STREAM, NULL);
    
    if( bRet )
    {
        if( m_ListenSocket.Listen() )
        {
            //m_bListen = true;
        }
    }
 
...
}
ListenerSocket.cpp
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
...
 
 
void ListenerSocket::OnAccept(int nErrorCode)
{
 
    CSocket socket;
    
    if( m_ConSock.m_hSocket == INVALID_SOCKET )
    {
        Accept( socket );
 
        SOCKET m_hSocket = socket.Detach();
        m_ConSock.Attach( m_hSocket );
        
        CString sAdr = "127.0.0.1";
        UINT nPort = 1022;
        GetSockName( sAdr,nPort);
        m_ConSock.GetPeerName( sAdr, nPort );
        CSocket::OnAccept( nErrorCode );
    }
    else
    {
        Accept( socket );
        socket.Close();
        CSocket::OnAccept( WSAEADDRINUSE );
    }
}
MySocket.cpp
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
...
 
void MySocket::OnReceive(int nErrorCode)
{
    int nRead;
    TCHAR szError[256];
    CString sAdr, str;
    UINT nPort;
    
    nRead = Receive( m_pBuffer, BUFFERSIZE);
 
    switch( nRead )
    {
        case 0:
        {
            Close();
        }
        break;
        case SOCKET_ERROR:
        {
            if( GetLastError() != WSAEWOULDBLOCK ) 
            {
                wsprintf( szError, "OnReceive error: %d", GetLastError() );
                AfxMessageBox( szError );
            }
        }
        break;
        default:
        {
            if( ( nRead != SOCKET_ERROR ) && ( nRead != 0 ) )
            {
                
                m_pBuffer[ nRead ] = '\0'; 
                m_RxBuffer = CString( m_pBuffer );
                
                
                SendResponse(m_pBuffer, nRead);   //В этой функции обрабатываем получанные данные
                GetPeerName( sAdr, nPort );
            }
        }
        break;
    }
    CSocket::OnReceive( nErrorCode );
}
 
...
 
void MySocket::m_SendFileCopy(CString str)  // После обработке нам сообщают что нужно передать файл этой функцией
{
    FILE *in = fopen(str,"rb");
    char *bufer = new char[BUFFERSIZE];      //буфер делал 4Мб
    int i = BUFFERSIZE;
    while(!feof(in))
    {
        int siz = fread(bufer, 1, i, in);
        if(siz < BUFFERSIZE)
            i = siz;
        Sleep(180);          // сделал паузу что бы успели данные передатся корректно.
        CSocket::Send(bufer, i, 0);
    }
    fclose(in);
    Sleep(180);    // тоже делаю паузу
    CString gg = "!DICOFEND";
    CSocket::Send(gg, gg.GetLength());
}
Что тут не корректно?

Добавлено через 19 минут
Кстати забыл добавить что тут:
The TCP must recover from data that is damaged, lost, duplicated, or
delivered out of order by the internet communication system. This
is achieved by assigning a sequence number to each octet
transmitted, and requiring a positive acknowledgment (ACK) from the
receiving TCP. If the ACK is not received within a timeout
interval, the data is retransmitted. At the receiver, the sequence
numbers are used to correctly order segments that may be received
out of order and to eliminate duplicates. Damage is handled by
adding a checksum to each segment transmitted, checking it at the
receiver, and discarding damaged segments.
возможно имелось в виду, что данные если они большие нарезаются кусками. Им присваиваются номера и отсылаются кусками. Т.е я например отсылаю 4Мб данных, а он разрезает на куски присваивая номера и отсылает. Тут я не спорю. Но ведь следующий 4Мб отосланных он может быть еще не нарезан. Ведь еще первая партия не было отправлена по локальной сети. А тут еще третья часть приходит (4Мб).
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
01.12.2014, 15:07
Приведите минимальный код, воспроизводящий проблему.
Чтобы его можно было вставить в Visual Studio и скомпилировать.

Добавлено через 1 минуту
А этого разве недостаточно для объяснения:

Цитата Сообщение от angoli Посмотреть сообщение
At the receiver, the sequence numbers are used to correctly order segments that
may be received out of order and to eliminate duplicates.
0
3 / 3 / 3
Регистрация: 28.03.2013
Сообщений: 45
01.12.2014, 15:47
At the receiver, the sequence numbers are used to correctly order segments that
may be received out of order and to eliminate duplicates.
Вот именно это говорится про сегменты. Те что назерались от 4Мб например. Но это не про другую часть данных что отсылается.

Пока исходный код на файловый обменник вылаживается. Подумай сам. Если ты говоришь что все становится в очереть, то где это все хранится? В оперативной памяти. А теперь представь что нужно отослать не 10Мб, а 20Гб фильма. И все это будет хранится в оперативной памяти, пока не передастся. Я думаю компьютер ляжет от этого если у него оператива меньше будет.

Добавлено через 9 минут
А вот и проект http://file.sampo.ru/7kwrwv/
Запускай файлы на разных ПК, естественно с подключением Ethernet
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
01.12.2014, 16:28
Цитата Сообщение от angoli Посмотреть сообщение
Вот именно это говорится про сегменты. Те что назерались от 4Мб например. Но это не про другую часть данных что отсылается.
Почитай то, что выделено красным.
И еще какую-нибудь толковую литературу по TCP, например
Таненбаума, Стивенсона или Снейдера. Там все это описано.

Для TCP-компонентов не имеет значения то, что где-то внизу летают,
перемешиваются, дублируются и отбрасываются пакеты и сегменты,
они видят лишь поток данных в обоих направлениях.

Цитата Сообщение от angoli Посмотреть сообщение
Подумай сам. Если ты говоришь что все становится в очереть, то где это все хранится? В оперативной памяти. А теперь представь что нужно отослать не 10Мб, а 20Гб фильма. И все это будет хранится в оперативной памяти, пока не передастся. Я думаю компьютер ляжет от этого если у него оператива меньше будет.
Все это давно разрулено в TCP системой под названием "плавающее окно".
Гугл -> TCP sliding window. TCP не будет ставить в очередь 20ГБ, если на той
стороне не готовы принять столько данных. Send просто заблокируется,
пока очередь не будет достаточно разгружена, и все.

Можно написать простой тест: клиент непрерывно шлет данные большими кусками,
без задержек, сервер делает recv в цикле по одному байту и с длительными паузами.
Если правильно все сделать, ни одного байта потеряно не будет, и никакой
перегрузки оперативки на отправляющей стороне тоже не возникнет.

Добавлено через 21 секунду
Цитата Сообщение от angoli Посмотреть сообщение
А вот и проект http://file.sampo.ru/7kwrwv/
Запускай файлы на разных ПК, естественно с подключением Ethernet
Вечером сегодня проверю и отпишусь.
0
3 / 3 / 3
Регистрация: 28.03.2013
Сообщений: 45
01.12.2014, 18:41
Send просто заблокируется, пока очередь не будет достаточно разгружена, и все.
Вопрос на засыпку. Выполняя этот код:
C++
1
CSocket::Send(bufer, i, 0);
Допустим полсе первого буфера(bufer) Send заблокировался. Проходит второй буфер Send заблокирован. Приходит третий буфер. Второй буфер затирается третьим. Send освободился и начинает передавать третий буфер. Разве такое не может быть?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.12.2014, 18:41
Помогаю со студенческими работами здесь

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

Передача координат транспорта в виде коротких сообщений
Разработать программу передачи координат транспорта г Москвы в виде коротких сообщений, обеспечивающих минимальный трафик. Для этого ввести...

Конструкторы,передача сообщений объектам и реакции объектов на сообщения в С++
Привет всем! Тему чуть-чуть понимаю,но задачу сделать не могу, вы не могли бы мне помочь с этим? вот задача:Создаваемый объект должен...

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru