Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/21: Рейтинг темы: голосов - 21, средняя оценка - 5.00
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12

Потоковая передача больших данных по TCP из Java в C#

21.09.2017, 08:22. Показов 4574. Ответов 14
Метки java (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день,

Прошу помощи в разборе полетов:
Задача: передать картинку с железки на которой установлена Linux + камера, клиент Windows.
Пишу сервер на Java, захватываю картинку, все нормально и начинаю пихать подключенному клиенту.
так вот, проблема такая, не все данные долетают, предположение что переполняется буффер сети.
То есть клиент на C# не усваивает обработать поток. малые объемы данных пролетают без потерь.
Пытался разбить пакет по 1024 байт, но после нескольких пакетов ломается...

Вопрос: Может быть кто-нибудь реализовывал подобное поделитесь опытом. или может как в теории это должно быть?

Код клиента на C#
Кликните здесь для просмотра всего текста

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
private void Bg_DoWork(object sender, DoWorkEventArgs e)
        {
            using (TcpClient socket = new TcpClient())
            {
                try
                {
                    socket.Connect((IPEndPoint)e.Argument);
                    NetworkStream ns = socket.GetStream();
                    byte[] Buffer = new byte[1024];
                    int countPack=0;
                    while (true)
                    {
                        string txt = "";
                        do
                        {
                            ns.Read(Buffer, 0, Buffer.Length);
                            txt += Encoding.Default.GetString(Buffer); // временно для дебага
                        }
                        while (ns.DataAvailable);
                        countPack++;
                        for (int i = 0; i < Buffer.Length; i++)
                            Buffer[i] = 0x00;
                        ((BackgroundWorker)sender).ReportProgress(countByte, txt);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Возникло исключение: " + ex.Message+ "\n  " );
                }
            }
        }


Код сервера на Java
Кликните здесь для просмотра всего текста

Java
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
 @Override
    public void run() {
        try {
            ServerSocket ss = new ServerSocket(tcpPort);
            System.out.println("server start:");
            while (true) {
                Socket socket = ss.accept();
                System.out.println("Connect client: " + socket.getInetAddress().getHostAddress());
                try {
                    Path path = Paths.get("/root/_DSC3886.jpg"); // для дебага пока что беру картинку
                    String dat=new String(Base64.getEncoder().encode(Files.readAllBytes(path))); //для дебага удобно читать
                    DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                    while (true) {
                        byte c=0;
                        out.write(dat.getBytes(),0,dat.getBytes().length);
                        Thread.sleep(200);
                    }
                } catch (EOFException eofex) {
                    System.out.println("!!-Disconect client");
                } catch (Exception x) {
                    System.out.println("!!-Disconect client");
                    x.printStackTrace();
                }
            }
        } catch (Exception ex) {
 
        }
    }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.09.2017, 08:22
Ответы с готовыми решениями:

Потоковая передача данных
Здравствуйте! Интересует идея создания сервера потоковой передачи музыки по WI-FI. В качестве сервера выступает обычный десктоп, на жестком...

Потоковая передача данных с телефона на компьютер
Друзья, товарищи. Запарился искать в гугле(и прочих равных поисковиках), а своих знаний пока не хватает. Задача стоит такая - телефон...

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

14
Эксперт .NET
 Аватар для Usaga
14135 / 9355 / 1350
Регистрация: 21.01.2016
Сообщений: 35,153
21.09.2017, 11:03
DaveMaks, у метода ns.Read нужно проверять возвращаемое значение, которое представляет из себя количество реально прочитанных байт или нуль, если соединение было разорвано другой стороной. Соответственно, именно это число и нужно использовать при манипуляциях с прочитанными данными (Buffer).

Добавлено через 1 минуту
Свойство ns.DataAvailable указывает сколько данных содержится в буфере сокета, а не всё количество ещё не принятых данных (такой информацией сокет просто не обладает).
0
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12
21.09.2017, 12:01  [ТС]
И в правду,
Сделал клиента так
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
using (TcpClient socket = new TcpClient())
            {
                socket.Connect((IPEndPoint)e.Argument);
                NetworkStream ns = socket.GetStream();
                byte[] pkgSize = new byte[8];
                long pkgSizeL = 0;
                int countByte = 0;
                while (true)
                {
                    string txt = "";
                    ns.Read(pkgSize, 0, 4);
                    Array.Reverse(pkgSize, 0, 4);
                    pkgSizeL = BitConverter.ToInt32(pkgSize, 0)+5;
                    byte[] Buffer = new byte[1024];
                    while (countByte < pkgSizeL)
                    {
                        int tmp= ns.Read(Buffer, 0, Buffer.Length);
                        if (tmp > 0)
                        {
                            countByte += tmp;
                            txt += Encoding.Default.GetString(Buffer);
                        }
                        else
                            break;
                    }
                    ((BackgroundWorker)sender).ReportProgress(countByte, txt);
                    countByte = 0;
                    Buffer = null;
                }
            }
а Сервер так
Java
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
@Override
    public void run() {
        try {
            ServerSocket ss = new ServerSocket(tcpPort);
            System.out.println("WebCam server start:");
            while (true) {
                Socket socket = ss.accept();
                System.out.println("Connect client: " + socket.getInetAddress().getHostAddress());
                try {
                    Path path = Paths.get("/root/_DSC3886.jpg");
                    String dat=new String(Base64.getEncoder().encode(Files.readAllBytes(path)));
                    DataInputStream in = new DataInputStream(socket.getInputStream());
                    DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                    String line = "";
                    while (true) {
                            byte[] IDpac= ByteBuffer.allocate(Integer.BYTES).putInt(dat.getBytes().length).array();
                            out.write(IDpac,0,IDpac.length);
                            out.write(dat.getBytes(),0,dat.getBytes().length);
                        System.out.println("Send: " + dat.getBytes().length+"b");
                        Thread.sleep(500);
                    }
                } catch (EOFException eofex) {
                    System.out.println("!!-Disconect client");
                } catch (Exception x) {
                    socket.close();
                    System.out.println("!!-Disconect client");
                    x.printStackTrace();
                }
            }
        } catch (Exception ex) {
 
        }
 
    }
0
Эксперт .NET
 Аватар для Usaga
14135 / 9355 / 1350
Регистрация: 21.01.2016
Сообщений: 35,153
21.09.2017, 12:21
DaveMaks, в строке №11 клиента вы снова забыли проверить что возвращает ns.Read(), а в №21 забыли, что Buffer может содержать меньше данных, чем надо. И конкатенация строк в цикле - фу-фу-фу. Используйте StringBuilder.

Добавлено через 1 минуту
Кстати, слабо вычислить Int32 из четырёх байт не прибегая к Array.Reverse и BitConverter.ToInt32?
1
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12
21.09.2017, 12:24  [ТС]
Да, я тут с Вами согласен, это все решится, и оптимизируется, вопрос был принять все куски данных. и понять алгоритм как это за пилить)
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
21.09.2017, 12:25
А зачем картинку преобразовывать в строку, а потом строку обратно в байты при отправке? Почему нельзя отправлять байты напрямую? Почему не использовать BinaryReader при получении данных?
0
Эксперт .NET
 Аватар для Usaga
14135 / 9355 / 1350
Регистрация: 21.01.2016
Сообщений: 35,153
21.09.2017, 12:26
DaveMaks, в строке №21 ошибка, а не задел для оптимизации. Это игнорировать нельзя.
0
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12
22.09.2017, 08:22  [ТС]
Как то так вот получилось и даже работает
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
using (TcpClient socket = new TcpClient())
            {
                try
                {
                    socket.Connect((IPEndPoint)e.Argument);
                    NetworkStream ns = socket.GetStream();
                    byte[] bufSize = new byte[4];
                    int pkgSize = countByte =0;
                    while (true)
                    {
                        cfile++;
                        ns.Read(bufSize, 0, bufSize.Length);
                        pkgSize = (bufSize[3] << 0 | bufSize[2] << 8 | bufSize[1] << 16 | bufSize[0] << 24);
                        StringBuilder txt = new StringBuilder((int)pkgSize);
                        byte[] Buffer = new byte[1024];
                        while (countByte < pkgSize)
                        {
                            int tmp = ns.Read(Buffer, 0, Buffer.Length);
                            if (!(tmp<0))
                            {
                                countByte += tmp;
                                txt.Append(Encoding.Default.GetString(Buffer,0, tmp));
                            }
                            for (int k = 0; k < Buffer.Length; k++)
                                Buffer[k] = 0x00;
                        }
                        ((BackgroundWorker)sender).ReportProgress(countByte, txt.ToString());
                        countByte = 0;
                        Buffer = null;
                        txt = null;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Возникло исключение: " + ex.ToString() + "\n  " + ex.Message);
                }
            }
java код сервера
Кликните здесь для просмотра всего текста

Java
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
@Override
    public void run() {
        try {
            ServerSocket ss = new ServerSocket(tcpPort);
            System.out.println("WebCam server start:");
            while (true) {
                Socket socket = ss.accept();
                System.out.println("Connect client: " + socket.getInetAddress().getHostAddress());
                try {
                    DataInputStream in = new DataInputStream(socket.getInputStream());
                    DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                    int i=0;
                    while (true) {
                        if (i>20)i=1;
                        Path path = Paths.get("/root/img/video_"+i+".jpg");
                        String dat = new String(Base64.getEncoder().encode(Files.readAllBytes(path)));
                        byte[] IDpac = ByteBuffer.allocate(Integer.BYTES).putInt(dat.getBytes().length).array();
                        out.write(IDpac, 0, IDpac.length);
                        out.write(dat.getBytes(), 0, dat.getBytes().length);
                    }
                } catch (EOFException eofex) {
                    System.out.println("!!-Disconect client");
                } catch (Exception x) {
                    socket.close();
                    System.out.println("!!-Disconect client");
                    x.printStackTrace();
                }
            }
        } catch (Exception ex) {
 
        }
    }
0
Эксперт .NET
 Аватар для Usaga
14135 / 9355 / 1350
Регистрация: 21.01.2016
Сообщений: 35,153
22.09.2017, 08:57
DaveMaks, в C# переменные типа Int инициализировать нулём не нужно, это за вас делает CLR. ns.Read принимающее размер данных вы всё ещё не проверяете на количество реально принятых данных. Обнулять содержимое буфера на каждой итерации нет нужды. Условие if (!(tmp<0)) некорректно. Нет проверки условия выхода из цикла.

Добавлено через 9 минут
Про инициализацию я фигню написал.
0
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12
22.09.2017, 09:42  [ТС]
Убрал строку стало намного быстрее )

C#
1
2
3
4
5
6
7
8
9
10
11
12
byte[] Packege = new byte[(int)pkgSize];
while (countByte < pkgSize)
                    {
                        int tmp = ns.Read(Buffer, 0, Math.Min(Buffer.Length, pkgSize-countByte) );
                        if (tmp > 0)
                        {
                            Array.Copy(Buffer, 0, Packege, countByte, tmp);
                            countByte += tmp;
                        }
                        for (int k = 0; k < Buffer.Length; k++)
                            Buffer[k] = 0x00;
                    }
0
Эксперт .NET
 Аватар для Usaga
14135 / 9355 / 1350
Регистрация: 21.01.2016
Сообщений: 35,153
22.09.2017, 09:52
DaveMaks, а где проверка на переполнение буфера Package? И buffer нулями забивать не надо - его содержимое всё равно будет переписано на следующей итерации. Вам нет необходимости всё прогонять через один буфер и копировать данные в другой. Метод Read имеет перегрузку (которую вы и используете), которая позволяет записывать данные в определённый участок буфера. Пользуйтесь этим.
0
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12
22.09.2017, 10:00  [ТС]
И buffer нулями забивать не надо - его содержимое всё равно будет переписано на следующей итерации.
Я тоже так думал, но бывают случаи когда прилетает фрагмент в 10байт, тогда мусор из предыдущего пакета забивает весь оставшийся массив.
а где проверка на переполнение буфера Package?
int tmp = ns.Read(Buffer, 0, Math.Min(Buffer.Length, pkgSize - countByte)); - больше не влезет)
0
Эксперт .NET
 Аватар для Usaga
14135 / 9355 / 1350
Регистрация: 21.01.2016
Сообщений: 35,153
22.09.2017, 10:07
DaveMaks, ничего он не забивает, так как вы используете из этого буфера ровно столько, сколько пришло. Поэтому вам должно быть всё равно, что в нём осталось от прошлой итерации.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
22.09.2017, 11:44
Вот эту жесть
Java
1
2
3
4
                        String dat = new String(Base64.getEncoder().encode(Files.readAllBytes(path)));
                        byte[] IDpac = ByteBuffer.allocate(Integer.BYTES).putInt(dat.getBytes().length).array();
                        out.write(IDpac, 0, IDpac.length);
                        out.write(dat.getBytes(), 0, dat.getBytes().length);
меняем на
Java
1
2
3
4
                        byte[] dat = Files.readAllBytes(path);
                        byte[] IDpac = ByteBuffer.allocate(Integer.BYTES).putInt(dat.length).array();
                        out.write(IDpac, 0, IDpac.length);
                        out.write(dat, 0, dat.length);
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
            using (TcpClient socket = new TcpClient())
            {
                try
                {
                    socket.Connect((IPEndPoint)e.Argument);
                    NetworkStream ns = socket.GetStream();
                    BinaryReader br = new BinaryReader(ns);
                    //int countByte = 0;
                    while (true)
                    {
                        int pkgSize = br.ReadInt32();
                        byte[] pkgData = br.ReadBytes(pkgSize);
                        // do something with pkgData...
                        //((BackgroundWorker)sender).ReportProgress(countByte, txt.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Возникло исключение: " + ex.ToString() + "\n  " + ex.Message);
                }
            }
0
 Аватар для DaveMaks
0 / 0 / 0
Регистрация: 21.09.2017
Сообщений: 12
22.09.2017, 16:28  [ТС]
Вообщем перепилил, все работает без потерь, чуть изменил формат пакета. Спасибо большое за наставление на путь истинный
Кликните здесь для просмотра всего текста

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
 int errors = 0;
            long frame = 0;
            if (((BackgroundWorker)sender).CancellationPending) return;
            while (true)
            {
                errors++;
                try
                {
                    using (TcpClient socket = new TcpClient())
                    {
                        socket.Connect((IPEndPoint)e.Argument);
                        NetworkStream ns = socket.GetStream();
                        int pkgSize = 0, countByte = 0;
                        byte[] buffer = new byte[5120];
                        int errCount = 0;
                        while (true)
                        {
                            if (((BackgroundWorker)sender).CancellationPending) return;
                            pkgSize = 6;
                            byte[] Packege = null;
                            int t = countByte= errCount = 0;
                            
                            while (countByte < pkgSize)
                            {
                                if (((BackgroundWorker)sender).CancellationPending) return;
                                if (errCount++>1000) {
                                    throw new Exception("Нет данных!");
                                }
                                t += ns.Read(buffer, t, Math.Min(buffer.Length, pkgSize - countByte));
                                if (Packege != null)
                                {
                                    Array.Copy(buffer, 0, Packege, countByte, t);
                                    countByte += t;
                                    t = 0;
                                    continue;
                                }
                                countByte += t;
                                if (countByte >= 6 && Packege == null)
                                {
                                    if (buffer[4] != 0x33 || buffer[5] != 0x33)
                                        throw new Exception("Ошибка пакета! ");
                                    pkgSize = (buffer[3] << 0 | buffer[2] << 8 | buffer[1] << 16 | buffer[0] << 24) + 2;
                                    Packege = new byte[pkgSize];
                                    countByte = t = 0;
                                    continue;
                                }
                            }
                            
                            if (Packege[Packege.Length - 2] == 0x33 && Packege[Packege.Length - 1] == 0x33)
                                ((BackgroundWorker)sender).ReportProgress(countByte, Packege);
                            else
                                throw new Exception("Ошибка пакета! ");
                            //Thread.Sleep(400);
                            frame++;
                        }
                        
                    }
                }
                catch (Exception ex)
                {
                    ((BackgroundWorker)sender).ReportProgress(0, errors.ToString() + " " + frame.ToString() + " " + Math.Round((float)errors / frame, 2).ToString());
                    Console.WriteLine("Возникло исключение: " + ex.ToString() + "\n  " + ex.Message);
                }
            }


Сервер
Кликните здесь для просмотра всего текста

Java
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
@Override
    public void run() {
        try {
            ServerSocket ss = new ServerSocket(tcpPort);
            System.out.println("WebCam server start:");
            while (true) {
                Socket socket = ss.accept();
                File[]fList;
                File F = new File("/root/img/");
                fList = F.listFiles();
                System.out.println("Connect client: " + socket.getInetAddress().getHostAddress());
                try {
                    //DataInputStream in = new DataInputStream(socket.getInputStream());
                    DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                    int i=0;
                    while (true) {
                        if (i>fList.length-1)i=0;
                        Path path = Paths.get("/root/img/video_"+i+".jpg");
                        byte[] dat = Files.readAllBytes(path);
                        byte[] IDpac = ByteBuffer.allocate(Integer.BYTES).putInt(dat.length).array();
                        out.write(IDpac, 0, IDpac.length);
                        out.write(new byte[]{0x33,0x33}, 0, 2);
                        out.write(dat, 0, dat.length);
                        out.write(new byte[]{0x33,0x33}, 0, 2);
                        System.out.println( String.valueOf(i)+"->"+ String.valueOf(dat.length)+" "+String.valueOf(IDpac.length));
                        i++;
                        Thread.sleep(40);
                    }
                } catch (EOFException eofex) {
                    System.out.println("!!-Disconect client");
                } catch (Exception x) {
                    socket.close();
                    System.out.println("!!-Disconect client");
                    //x.printStackTrace();
                }
            }
        } catch (Exception ex) {
 
        }
 
    }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.09.2017, 16:28
Помогаю со студенческими работами здесь

СС1101 и "Потоковая" передача данных. Есть проблема
Здравствуйте Столкнулся с трудностью передачи звука. С настройками по умолчанию, после длительной передачи, приходят пустые пакеты. ...

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru