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

Функция приема данных с сокета

15.10.2015, 23:14. Показов 1780. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте делаю клиент сервер
смысл в том что после соединения клиента с сервером
сервер должен передать файл на сторону клиента
1) send-отправляет номер папки
2)send -размер файла
3)send-имя файла
4) дальше в цикле идет передача данных(передача файла)


код сервера



C++ (Qt)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//сервер на потоках
#include <QCoreApplication>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <fcntl.h>
#include <pthread.h>
#include <QFile>
#include <QTime>
int i=0;
 
using namespace std;
 
//функция обработки потока подаем файловый дескриптор связанный с клиентом
void* potokfunc(void* ps)  //начало потока функция
{  // после того как клиент соединился
    i=i+1;
    int rez;
    int sc = *(int*)ps;
    sched_yield();
    char buf3[2048];
    char buf2[1000];
    memset(buf2,0,sizeof(buf2)); //очищаем буфер
    memset(buf3,0,sizeof(buf3)); //очищаем буфер
 
    sprintf(buf2,"%d",i);
    //cout<<"НОМЕР ПАПКИ="<<buf2<<endl;
    //ОТПРАВЛЯЕМ НОМЕР ПАПКИ
 
 
    sleep(2);
    rez=send(sc,buf2,strlen(buf2),0);
    if (rez>0)
    {
        printf("номер папки успешно отправлен\n");
    }
    else
    {
        close(sc);
        return 0;
    }
 
 
    memset(buf2,0,sizeof(buf2)); //очищаем буфер данных
    //ОТПРАВЛЯЕМ РАЗМЕР ПАПКИ
    QFile e("/qqq");
    long int razmer=e.size();
    sprintf(buf2,"%d",razmer);
    //cout<<"РАЗМЕР ПАПКИ="<<razmer<<endl;
    sleep(2);
    int rz=send(sc,buf2,strlen(buf2),0);  //размер файла
    if (rz>0) //
    {
        printf("Передан размер файла \n");
    }
    else
    {
        close(sc);
        return 0;
    }
 
    memset(buf2,0,sizeof(buf2)); //очистили
    //ОТПРАВЛЯЕМ ИМЯ ФАЙЛА
    sleep(2);
    sprintf(buf2,"%s","qqq");
 
    //cout<<"ИМЯ ФАЙЛА="<<buf2<<endl;
    rz=send(sc,buf2,sizeof(buf2),0);  //имя файла
    if (rz>0)
    {
        printf("передано имя файла\n");
    }
    else
    {
        close(sc);
        return 0;
    }
 
    char *jj=QString("/qqq").toLocal8Bit().data();
    sprintf(buf2,"%s",jj);
    FILE *f=fopen(buf2,"rb");  // открываем файл на побайтное чтение
    if (f!=NULL)
    {
        while (1)
        {
            memset(buf3,0,sizeof(buf3));  //буфери для приема данных
            int rez=fread(buf3,1,sizeof(buf3),f);
            if (rez>0)  // если мы считали из файла в буфер
            {
                 //cout<<"OTPRAVLYAEM= "<<buf3<<endl;
                rz=send(sc,buf3,rez,0);
                if (rz>0)  //отправлено
                {
                    //cout<<"otpravleno= \n"<<rz<<endl;
                    razmer=razmer-rz;
                    printf("передано= %d байт\n",rz);
                }
                if (razmer==0)
                {
                    printf("весь файл отправлен\n");
                    break;
                }
            }
        }
        fclose(f);
    }
    else
    {
        memset(buf3,0,sizeof(2048));  //буфери для приема данных
        printf("файл не открыт для чтения \n");
    }
 
    return NULL;
}
 
 
int main(int argc, char *argv[])
{
    if (QFile("/1000ARM").exists())
    {
        system("rm -r /1000ARM");
    }
    QFile h("/logserver");
    h.remove();
    if (h.open(QIODevice::WriteOnly)==true)
    {
        h.close();
    }
 
    system("mkdir /1000ARM");
    char buf[100];
    memset(buf,0,sizeof(buf));
    struct sockaddr_in addr;
    struct sockaddr_in client;
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    addr.sin_port=htons(6643);
    addr.sin_family=AF_INET;
 
    int fd=socket(AF_INET,SOCK_STREAM,0);   // создаем сокет
    if (fd<0)
    {
        printf("Ошибка создания дескриптора\n");
        return 0;
    }
    //fcntl(fd,F_SETFL,O_NONBLOCK);
    int rez=bind(fd,(sockaddr *) &addr,sizeof(addr));  //привязываем сокет к конкретному адресу
    if (rez!=0)
    {
        printf("Ошибка привязки адреса и порта к сокету\n");
        return 0;
    }
    rez=listen(fd,1000);  //даем право сокету принимать соединения
    if (rez!=0)
    {
        printf("Ошибка принятия соединений");
        return 0;
    }
    printf("сервер запущен жду подключения\n");
 
 
    int fda;
    int truefda;
    QTime t;
    t.start();
    //QFile h("/logserver");
    if (h.open(QIODevice::Append)==true)
    {
        h.write("НАЧАЛО РАБОТЫ=0");
        h.close();
    }
    while(1)
    {
        while(1)
        {
            int len=sizeof(addr);
            fda=accept(fd,(sockaddr *) &addr,(socklen_t *) &len);
            //fda=accept(fd,NULL,NULL);
            if (fda<0)
            {
                continue;  // если нет подключения
            }
            else //есть подключение
            {
                truefda=fda;
                break;
            }
        }
 
        printf("произошло подключение создаю поток\n");
        pthread_t tid;  //создали объект потока
        int jj=pthread_create(&tid, NULL, &potokfunc, &truefda);    //передаем связный файловый дескриптор
        int vr=t.elapsed();
        if (h.open(QIODevice::Append)==true)
        {
            h.write(QString::number(vr).toLocal8Bit());
            h.write("\n");
            h.close();
        }
        if (jj!=0)
        {
 
            printf("поток не создан\n");
        }
        sched_yield();
 
    }
 
 
    return 0;
}
код клиента

C++ (Qt)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <QCoreApplication>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <fcntl.h>
#include <QFile>
#include <QDir>
 
 
 
int main(int argc, char *argv[])
{
 
    char buf[100];
    char buf3[2048];
    memset(buf3,0,sizeof(buf3));
    memset(buf,0,sizeof(buf));
    int fd=socket(AF_INET,SOCK_STREAM,0);
    if (fd<0)
    {
        printf("ошибка создания сокета \n");
        exit(0);
       // return 0;
    }
    struct sockaddr_in addr;
    addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
    addr.sin_port=htons(6643);
    addr.sin_family=AF_INET;
    int rez=connect(fd,(sockaddr *)&addr,sizeof(addr));
    if (rez!=0)
    {
        printf("ошибка присоединения к серверу \n");
        exit(0);
        //return 0;
    }
    printf("клиент запущен \n");
 
 
    QString papka;
    rez=recv(fd,buf,sizeof(buf),0);  // принимаем номер папки от сервера  1прием
    if (recv>0)  //пришел номер папки
    {
        printf("nomerpapki=%s\n",buf);
        QDir a;
        QString ff=QString("/1000ARM/")+QString(buf);
        papka=QString("/1000ARM/")+QString(buf);
        a.mkdir(ff);
    }
    else
    {
        close(fd);
        exit(0);
        //return 0;
    }
    memset(buf,0,sizeof(buf));
    int razmer;
    //ПРИНИМАЕМ РАЗМЕР ФАЙЛА
    rez=recv(fd,buf,sizeof(buf),0); //2прием
    if (rez>0)
    {
        razmer=QString(buf).toInt();
        printf("RAZMERCHIK=%d\n",razmer);
 
    }
    else
    {
        close(fd);
        exit(0);
        //return 0;
    }
 
 
    memset(buf,0,sizeof(buf));
 
 
    //ПРИНИМАЕМ ИМЯ ФАЙЛА
    rez=recv(fd,buf,sizeof(buf),0);  //3 прием
    if (rez>0)
    {
        printf("imyafaila=%s \n",buf);
    }
    else
    {
        printf("Имя файла не поступило");
        close(fd);
        //return 0;
        exit(0);
    }
 
//        rez=recv(fd,(char *) &buf3,sizeof(buf3),0);
//        if (rez>0)
//        {
//            printf("получили=%s\n",buf3);
 
//        }
 
    memset(buf3,0,sizeof(buf3));
 
    QString gg=papka+QString("/")+QString(buf);
    char *a=gg.toLocal8Bit().data();
    printf("IMYA_FAILA= %s\n",a);
    memset(buf,0,sizeof(buf));
    //ПРИНИМАЕМ САМ ФАЙЛ
    FILE *f=fopen(a,"wb");  // создали файлик
    if (f!=NULL)
    {
        while(1)
        {
            int rez=recv(fd,buf3,sizeof(buf3),0);
            if (rez>0)  // если данные получили
            {
                printf("что получили= %s\n",buf3);
                int rz=fwrite(buf3,1,rez,f);  //читаем данные в буфер сколько приняли
                if (rz>0)  //сколько записали
                {
                    printf("записано данных=%d\n",rz);
                    razmer=razmer-rz;
                }
            }
            if (razmer==0)  //все прочитали
            {
                printf("весь файл принят\n");
                break;
            }
        }
        fclose(f);
    }
    else
    {
        memset(buf3,0,sizeof(buf3));
        printf("файл не может быть создан \n");
    }
    exit( EXIT_SUCCESS );
    //return 0;
}
в итоге у меня получается так
1)номер папки приходит нормально
2)размер файла тоже приходит
3)имя файла тоже приходит
но когда я начинаю отправлять сам файл()
то происходит следующее(файл состоит из 4 букв "a")
1)со стороны сервера все нормально он считывает в буфер 4 байта
2) и отправляет 4 байта
но со стороны клиента

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
int rez=recv(fd,buf3,sizeof(buf3),0);
            if (rez>0)  // если данные получили
            {
                printf("что получили= %s\n",buf3);
                int rz=fwrite(buf3,1,rez,f); 
                if (rz>0)  //сколько записали
                {
                    printf("записано данных=%d\n",rz);
                    razmer=razmer-rz;
                }
            }
почему то данные приходят recv возвращает больше 0
C++ (Qt)
1
printf("что получили= %s\n",buf3);
но когда я распечатываю пусто
а
C++ (Qt)
1
printf("записано данных=%d\n",rz);
записывает 904 байта почему то
что может быть?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.10.2015, 23:14
Ответы с готовыми решениями:

Функция recv(), есть ли какой-нибудь признак завершения чтения из сокета?
У меня такой вопрос если я передаю некоторые данные с TCP клиента на сервер и на сервере запускаю функцию recv() через бесконечный цикл, то...

Функция приема разных типов в классе
Сразу скажу что надо. Есть функция pow(), так вот она принимает разные типы данных. У меня класс хочу сделать тоже самое. Подскажите как, я...

Универсальная функция для приема разных двумерных массивов
В программе у меня много двумерных массивом разной размерности. Мне нужна одна функция (общая) чтобы работала на все массивы. Функция...

2
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
16.10.2015, 15:27
потому что это TCP когда с одной стороны послали 3 байта п потом 10 байт, то на принимающей стороне прочитате или 13, или 10 а потом 3, или еще что то)
0
Задачи выполнил, ушёл
27 / 30 / 7
Регистрация: 16.10.2015
Сообщений: 345
18.10.2015, 03:27
Откуда у автора такие проблемы, по-идее сначала надо изучить как работает передача данных.
Программу по передаче файлов надо вообще аналитически разрабатывать и такое понятие как "отладка алгоритма" здесь вообще не уместно!
Ну как можно так разрабатывать программы, без проектной документации и анализа кода... это же всё-таки передача файлов, нету никакой гарантии что программа работает так как задумано, потому что "тут отладка, там отладка"...
Вы не поверите, но у меня даже сложная программа работает сразу, с первого раза, без отладки.
Сначала я создаю проектную документацию к ней, где подробно всё расписывается, затем уже просто по ней создаётся исходный код. Всяких ошибок, тем более логических, просто быть не может, код постоянно проверяется (верифицируется) на соответствие проектной документации...
Постоянная отладка для новичков, но не для профессионалов...
Извините, но уже просто хотелось донести мысль, я просто люблю хорошо написанный и проверенный код, я уверен, многие любят.

Добавлено через 19 минут
Автор, кстати, твой код просто нельзя верифицировать, он не корректно структурирован, я занимаюсь верификацией кода, этот код не годится для итоговой программы никак полностью:
комментарии то большими, то малыми буквами, имена случайные и некорректные, пробелы не в тех местах, нарушена стилистика, и другое...
Просто это программа для передачи файлов, только поэтому я и придрался)
Если хочешь быть профессионалом, пиши код так, как будто пишешь совершенный код.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.10.2015, 03:27
Помогаю со студенческими работами здесь

База данных с возможностью приема данных из файлов Excel
Здравствуйте Уважаемые! В &quot;Delphi для начинающих&quot; по этому вопросу НИКТО не помог:( Может здесь я найду помощь? Подскажите, где...

Скрипт приема данных
Можно для примера,скрипт для приёма данных от программы. То есть залил например скрипт на хостинг ,с программы с делал пост запрос на...

Фильтр приема данных
Добрый день, к МК по UART подключено устройство от которого по запросу приходят следующего вида сообщения: ...

Подскажите алгоритм приема данных
У меня есть небольшой радиомодуль который цифрует эфир и выдает серию ноликов и единичек. &lt;Изображение удалено&gt; Посылки...

Копирование сокета или передача сокета в функцию
Добрый день всем, столкнулся с тем что не могу скопировать сокет. boost::asio::ip::tcp::socket socket(io_service); ...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru