С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/32: Рейтинг темы: голосов - 32, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
1

Linux. Передача объектов через сокеты. Как?

30.03.2012, 10:55. Показов 6345. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
День добрый, господа! Мое первое сообщение на форуме, прошу любить и жаловать)

Написал небольшой сервер и клиент, клиент отправляет строку, сервер получает и отсылает обратно. Ну в общем классический пример для таких новичков как я
Все отлично работает, все счастливы...
Решил усложнить задачу и отправлять объект IplImage из openCV.
IplImage* image = 0;
А теперь, собственно, вопрос к знатокам, как это сделать?
Вроде как нужна сериализация?
Пожалуйста, подправьте мой код для передачи строк, чтобы я понял, как правильно передавать объект!

Собственно, сервер:
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
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
 
// Порт сервера
#define PORTUM 1500
 
int main()
{
    int s;      // Идентификатор основного сокета
    int ns;     // Идентификатор дочернего сокета
    int pid;    // ID процесса
    int nport;  // Номер порта
    struct sockaddr_in serv_addr;
    struct sockaddr_in clnt_addr;
    char buf[80];
    char hname[80];
    /* Преобразуем порядок следования байтов к сетевому формату*/
    nport = PORTUM;
    nport = htons((u_short)nport);
    /* Создаем сокет TCP*/
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("Ошибка вызова socket()\n"); 
        return -1;
    }else {
        printf ("Сокет с идентификатором %i успешно создан.\n", s);
    }
    /*Задаем адрес коммуникационного узла*/
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = nport;
    /*Свяжем сокет с этим адресом*/
    if (bind(s, (struct sockaddr *)&serv_addr, 
        sizeof(serv_addr)) == -1) {
        perror("Ошибка вызова bind()\n"); 
        return -1;
    }else {
        printf ("bind() успешно отработал.\n");
    }
 
    /*Сообщение с указанием адреса сервера*/
    fprintf(stderr, "Сервер готов: %s\n", inet_ntoa(serv_addr.sin_addr));
 
    /*Начинаем слушать с очередью до 5ти запросов*/
    if (listen(s, 5) == -1) {
        perror("Ошибка вызова listen()\n"); 
        return -1;
    }else {
        printf ("listen() успешно запущен, слушаем...\n");
    }
 
    /*Бесконечный цикл получения и обработки запросов*/
    while(1)
    {
        socklen_t addrlen; 
        bzero(&clnt_addr, sizeof(clnt_addr));
        addrlen = sizeof(clnt_addr);
        /*Принимаем входящий запрос*/
        if ((ns = accept(s, (struct sockaddr *)&clnt_addr,
            &addrlen)) == -1) {
            perror("Ошибка вызова accept()\n"); 
            return -1;
        }else {
            printf ("Запрос на connet принят. Обработка...\n");
        }
        /*Информация о клиенте*/
        fprintf(stderr, "Клиент = %s\n", inet_ntoa(clnt_addr.sin_addr));
        
        /*Создаем процесс для работы с клиентом*/
        if ((pid = fork()) == -1) {
            perror("Ошибка вызова fork()\n"); 
            return -1;
        } else {
            printf ("Процесс для обработки успешно создан.\n");
        }
        if (pid == 0) {
            int nbytes;
            int fout;
            /*Мы в дочернем процессе, закрываем родительский сокет*/
            close(s);
            /*Получаем сообщение и передаем его обратно*/
            while ((nbytes = recv(ns, buf, sizeof(buf), 0)) != 0)
            {
                printf("Получено сообщение: %s,\nпосылаем обратно...\n", buf);
                send(ns, buf, sizeof(buf), 0);
            }
            close(ns);
            printf("Обработка закончена, дочерний процесс закрываем.\n");
            exit(0);
        }
        /*Мы в родительском процессе, сокет ns не нужен*/
        close(ns);
    }
    return 0;
}
Клиент:
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
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
 
// Порт сервера
#define PORTUM 1500
 
int main(int argc, char* argv[])
{
    int s;      // Идентификатор основного сокета
    int pid;    // ID процесса
 
    struct sockaddr_in serv_addr;
 
    struct hostent *hp;
    char buf[80] = "Как много нам открытий чудных...";
    
    /*Обрабатываем доменное имя хоста, полученное в качестве аргумента*/
    if ((hp = gethostbyname(argv[1])) == 0) {
        perror("Ошибка вызова gethostbyname()\n"); 
        return -1;
    }
 
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = hp->h_addrtype;
    bcopy(hp->h_addr, &serv_addr.sin_addr, hp->h_length);
    serv_addr.sin_port = htons(PORTUM);
 
    /* Создаем сокет TCP*/
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("Ошибка вызова socket()\n"); 
        return -1;
    }else {
        printf ("Сокет с идентификатором %i успешно создан.\n", s);
    }
 
    /*Сообщение с указанием адреса сервера*/
    fprintf(stderr, "Адрес сервера: %s\n", inet_ntoa(serv_addr.sin_addr));
 
    /*Создаем канал*/
    if (connect(s, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
        perror("Ошибка вызова connect()\n"); 
        return -1;
    }else {
        printf ("Соединение с сервером открыто, передача сообщения...\n", s);
    }   
 
    /*Отправим серверу сообщение*/
    send(s, buf, sizeof(buf), 0);
    if(recv(s, buf, sizeof(buf), 0) < 0) {
        perror("Ошибка вызова recv()\n"); 
        return -1;
    }else {
        printf("Получено сообщение от сервера: %s\n", buf);
    }
 
    close(s);
    printf("Клиент завершил работу");
 
    return 0;
}
0
IT_Exp
Эксперт
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
Блог
30.03.2012, 10:55
Ответы с готовыми решениями:

передача массива через сокеты, как?
собственно сабж, пробовал много через что, но тот или ной вариант не подходит. вот к примеру...

Передача сообщения в Windows-Linux (сокеты)
Пытаюсь написать чат с передачей сообщения. Использую сокеты. Пока чат простейший - клиент и...

Ввод и вывод команды через сокеты linux
По книге &quot;сетевое программирование в unix&quot; сделал tcp клиент и сервер. Подскажите как сделать так,...

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

25
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
30.03.2012, 14:38  [ТС] 2
Увы, мне это, похоже, мало поможет..

Добавлено через 2 часа 36 минут
Так, раз никто не отвечает, попробую задать вопрос конкретнее.

Есть стандартная функция
C++
1
ssize_t send(int s, const void *msg, size_t len, int flags);
Есть класс openCV под названием IplImage.
Объект класса IplImage объявлен в программе так:
C++
1
IplImage* image = 0;
Вопрос: как отправить image с помощью функции send()? Или его нужно отправлять как-то иначе? Насколько я понимаю, размер его нефиксирован.

Если дадите что-то почитать чтоб я сам смог разобраться, велкам!!!
0
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
30.03.2012, 16:51 3
Цитата Сообщение от Q-gecHuK Посмотреть сообщение
Вроде как нужна сериализация?
угу.
http://www.boost.org/doc/libs/... index.html
0
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
30.03.2012, 17:03  [ТС] 4
Цитата Сообщение от niXman Посмотреть сообщение
Так, я тут выяснил, что openCV имеет встроенные возможности сериализации.
http://robocraft.ru/blog/computervision/299.html
Т.е. я могу этот объект запихнуть в xml а на другой стороне перевести обратно в объект класса. Урра!
Тогда остался вопрос - а как мне с помощью вышеупомянутой функции send() отправить этот xml файл?
0
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
30.03.2012, 17:10 5
Этот объект, он как устроен? Если он занимает в памяти единый кусок, то можно его отправлять без всяких преобразовываний, представив как char массив.
0
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
30.03.2012, 19:14  [ТС] 6
Цитата Сообщение от Union Посмотреть сообщение
Этот объект, он как устроен? Если он занимает в памяти единый кусок, то можно его отправлять без всяких преобразовываний, представив как char массив.
Сейчас поищу, как он устроен. Если он и правда монолитный, как его в этом случае преобразовать в char массив? И как преобразовать обратно?
И еще, может быть подскажете, как передать xml файл, который можно получить встроенными средствами openCV? (см. предыдущий пост)

Добавлено через 1 час 41 минуту
Так, выяснилось, что можно закодировать картинку в вектор байт. Насколько я понимаю, эта CvMat уже состоит из последовательный байтов. Попробую передать ее...
C++
1
2
3
4
5
6
7
8
9
IplImage* imageold = 0;
    IplImage* imagenew = 0;
 
    char* filename = "Img1.jpg";
        // получаем картинку
        imageold = cvLoadImage(filename,1);
 
    // кодируем картинку и сохраняем результат в вектор байт
        CvMat* mat = cvEncodeImage(".jpg", imageold);
Добавлено через 15 минут
Нет, увы, эти объекты не последовательные... Остается передавать xml. Как это сделать через send(), подскажите пожалуйста?
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
01.04.2012, 15:54 7
Цитата Сообщение от Union Посмотреть сообщение
Если он занимает в памяти единый кусок, то можно его отправлять без всяких преобразовываний, представив как char массив.
Ну лучше сериализация.
Цитата Сообщение от Q-gecHuK Посмотреть сообщение
Как это сделать через send(), подскажите пожалуйста?
просто как строку. Указатель на начало и размер.
0
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
02.04.2012, 09:54  [ТС] 8
Все, более менее разобрался, что к чему. Спасибо!

Добавлено через 15 часов 16 минут
Нашел отличную статью про передачу видео из openCV по TCP/IP.
Мало ли, вдруг пригодится кому.
http://nashruddin.com/StrEAMin... He_nEtWoRk
0
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.04.2012, 19:32 9
Цитата Сообщение от Q-gecHuK Посмотреть сообщение
Мало ли, вдруг пригодится кому.
http://nashruddin.com/StrEAMin... He_nEtWoRk
ты-то сам ту статью читал?
а ничего, что там передается 1000 BMP`шек в секунду, что, равняется, примерно ~77 Мбайт в секунду, при разрешении 320*240
скайп отдыхает))
0
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
02.04.2012, 20:27  [ТС] 10
Цитата Сообщение от niXman Посмотреть сообщение
ты-то сам ту статью читал?
а ничего, что там передается 1000 BMP`шек в секунду, что, равняется, примерно ~77 Мбайт в секунду, при разрешении 320*240
скайп отдыхает))
Да, я ее прочитал и повторил у себя. По локалке с вебкамеры в разрешении 640 на 480 нормально работает. А вот с интернетом беда...
Может быть подскажете мне более рациональный способ передачи видео? Был бы очень признателен! Нужно передавать видео с вебкамеры через интернет с приемлемым fps.

Поправочка... Сейчас проверил сетевой трафик при передаче 640*480 по локалке, в среднем 2.5 Мбайт/сек, что уж никак не "77 Мбайт в секунду, при разрешении 320*240 ". Но это все равно много для интернета, так что жду совета!

Добавлено через 23 минуты
(смотрю сейчас в сторону H.264)
0
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.04.2012, 20:39 11
Цитата Сообщение от Q-gecHuK Посмотреть сообщение
проверил сетевой трафик при передаче 640*480 по локалке, в среднем 2.5 Мбайт/сек
сделай вывод переменной imgsize из кода сервера и покажи какую задержку используешь.
0
0 / 0 / 0
Регистрация: 30.03.2012
Сообщений: 7
02.04.2012, 21:06  [ТС] 12
Тут видно что размер одной картинки 300кб, fps около 10 кадров в секунду, вот и получается трафик около 3 МБайт/сек.

Так что скажете насчет H.264 ? Может быть знаете ссылки на какие-то реализации передачи видео по этому протоколу? А то пока не могу найти ничего готового..(
Миниатюры
Linux. Передача объектов через сокеты. Как?  
0
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.04.2012, 21:33 13
Цитата Сообщение от Q-gecHuK Посмотреть сообщение
fps около 10 кадров в секунду
я-то говорил о 1000 картинках. ровно столько отправляет сервер по приведенной ссылке.

Цитата Сообщение от Q-gecHuK Посмотреть сообщение
Так что скажете насчет H.264 ?
поищи по этому разделу...

в одной из тем, я говорил о том, что использовал libpng. что позволило сократить объем трафа в 12 раз.

Добавлено через 18 минут
Цитата Сообщение от Q-gecHuK Посмотреть сообщение
размер одной картинки 300кб
ах да. я с ноликом перебрал)
0
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 11:54 14
И все же что тогда делает cvEncodeImage() и как получить картинку в памяти что бы она выглядела так же как файле(заданного формата) ?
0
Эксперт С++
3072 / 1410 / 425
Регистрация: 19.01.2009
Сообщений: 3,889
23.11.2014, 13:45 15
Avazart, cvEncodeImage преобразует байты исходного изображения в зависимости от указанного формата.

Вторым аргументом данной функции она ожидает указатель на структуру IplImage, у которой есть член с названием imageData - указатель на выравненные данные изображения. widthStep = кол-во байт в строке вместе с выравниванием.
1
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 13:47 16
Цитата Сообщение от schdub Посмотреть сообщение
Avazart, cvEncodeImage преобразует байты исходного изображения в зависимости от указанного формата.
Во что преобразовывает?

В набор битов значений пикселей? Набор битов изображения, со всеми заголовками, палитрами итп?

Как нужна функция нечто вроде cvSaveImage() но типа cvSaveImageToBuffer(IplImage* img, char* buffer,size_t size);
0
Эксперт С++
3072 / 1410 / 425
Регистрация: 19.01.2009
Сообщений: 3,889
23.11.2014, 13:48 17
Кстати, С++ аналог cvEncodeImage() - cv::imencode().
0
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 13:54 18
Т.е. что бы если мы записали буфер как есть файл, получили читаемую картинку.

Добавлено через 1 минуту
Цитата Сообщение от schdub Посмотреть сообщение
Кстати, С++ аналог cvEncodeImage() - cv::imencode().
Смотрел исходники cvEncodeImage() вызывает вроде изнутри cv::imencode().
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
23.11.2014, 14:06 19
Первый параметр imencode определяет формат изображения JPEG, PNG и т.д. Ну а стандартный JPEG/PNG можно прочитать везде.
0
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 14:14 20
Так а что на выходе получаем?
0
23.11.2014, 14:14
BasicMan
Эксперт
19315 / 2622 / 84
Регистрация: 17.02.2009
Сообщений: 10,364
Блог
23.11.2014, 14:14
Помогаю со студенческими работами здесь

Передача из TImage через сокеты
Привет, ребят. написал клиент и сервер . что на TImage клиента нужно передать на TImage сервера. Ну...

Передача файла через сокеты
Столкнулся со следующей проблемой: передаю файл с клиента на линуксе на сервер на винде. Файл...

Передача файлов через сокеты
Есть сервер import java.io.DataOutputStream; import java.io.File; import...

Передача вектора через сокеты
Добрый день. Помогите разобраться, передаю вектор AnsiString через ClientSocket ServerSocket. ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Блоги программистов
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного суматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
Это мы не проходили, это нам не задавали...(аси­­хронный счётчик с управляющим сигналом задержки).
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
Применение компонентов PrimeVue в Vue.js 3 на TypeScript
BasicMan 04.01.2025
Введение в PrimeVue и настройка окружения PrimeVue представляет собой мощную библиотеку компонентов пользовательского интерфейса для Vue. js 3, которая предоставляет разработчикам богатый набор. . .
Как стать Senior developer
cpp_developer 04.01.2025
В современной индустрии разработки программного обеспечения позиция Senior Developer представляет собой не просто следующую ступень карьерной лестницы, а качественно новый уровень профессионального. . .
Что известно о дате выхода Windows 12 и чего от нее ждать
IT_Exp 04.01.2025
В мире технологий постоянно происходят изменения, и операционные системы не являются исключением. Windows 11, выпущенная в октябре 2021 года, принесла множество инноваций и улучшений, но. . .
Что новенького в .NET Core 9
Programming 04.01.2025
Обзор ключевых изменений в . NET Core 9 Платформа . NET Core продолжает активно развиваться, и версия 9 представляет собой значительный шаг вперед в эволюции этой технологии. Новый релиз. . .
Инструкция по установке python3.13.1 в Debian 12
AlexSky-coder 03.01.2025
sudo apt update sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget. . .
Затестил триггеры. архив проекта прилагаю с GOA файлами в настройках архиватора проектов.
Hrethgir 03.01.2025
В этот раз нет закольцованности, потому что от неё только глюки, как я понял, логика не вырезанная. Триггеры очень быстрые если верить измерениям с помощью анализатора от Gowin. Есть ещё регистры,. . .
Python в помощь DevOps
IT_Exp 03.01.2025
Причины использования Python в работе DevOps Python стал неотъемлемой частью мира DevOps, и это не случайно. Этот язык программирования обладает множеством преимуществ, которые делают его. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru