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

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

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

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

Написал небольшой сервер и клиент, клиент отправляет строку, сервер получает и отсылает обратно. Ну в общем классический пример для таких новичков как я
Все отлично работает, все счастливы...
Решил усложнить задачу и отправлять объект 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.03.2012, 10:55
Ответы с готовыми решениями:

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

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

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

25
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
23.11.2014, 14:48
Студворк — интернет-сервис помощи студентам
буфер с JPEG/PNG. О форматах и параметрах imwrite
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 15:37
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
буфер с JPEG/PNG.
Ну так в каком виде, как я понял там сырые данные без заголовков итп, и вообще в неведомом формате.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
23.11.2014, 16:49
Цитата Сообщение от Avazart Посмотреть сообщение
Ну так в каком виде, как я понял там сырые данные без заголовков итп, и вообще в неведомом формате.
Формат и вид JPEG'а известен. Получаешь то же, что при обычном чтения JPEG файла в буфер.
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 17:11
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Формат и вид JPEG'а известен. Получаешь то же, что при обычном чтения JPEG файла в буфер.
Тогда значит я что-то не так делаю.

Добавлено через 10 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <fstream>
 
IplImage* img = cvLoadImage("1.jpg", CV_LOAD_IMAGE_UNCHANGED);
CvMat* mat = cvEncodeImage(".jpg", img);
 
if(mat)
{
    std::ofstream ofs("2.jpg",std::ios::binary);
    if(ofs)
    {
      ofs.write(mat->data.ptr,mat->width* mat->height);
      ofs.close();
    }
}
 
cvReleaseImage(&img);
Да действительно работает, ошибка видимо в другой части кода была.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
23.11.2014, 17:31
для кого придумали API на 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
32
33
34
35
36
37
38
39
40
41
#include <vector>
#include <fstream>
 
#include <boost/lexical_cast.hpp>
 
#include "opencv2/opencv.hpp"
 
using namespace cv;
 
int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;
 
    Mat edges;
    namedWindow("edges",1);
    std::vector<unsigned char> buff;
    buff.reserve(1024*1024*4); //4 mb
    
    int i = 0;
    for(;;)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        if(imencode(".jpeg", frame, buff))
        {
            ++i;
            std::string name = "img"+boost::lexical_cast<std::string>(i)+".jpeg";
            std::cout<<"write"<<" "<< name <<std::endl;
            std::ofstream ofs (name.c_str(), std::ios::binary);
            ofs.write(reinterpret_cast<char*>(&buff[0]), buff.size());
            ofs.close();
 
        }
        imshow("edges", frame);
        if(waitKey(30) >= 0) break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2014, 17:35

Не по теме:

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
для кого придумали API на C++?
В C++Builder плюсовый интерфейс не работает (не компилиться c плюсовыми *.hpp)
По этому пробую пока так, если нет то уже в Qt перейду и там уже на ++


Да и забыл в коде:
C++
1
cvReleaseMat(&mat);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.11.2014, 17:35

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru