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

Передача двоичного файла через TCP сокет

11.02.2012, 19:39. Показов 14937. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Двоичный файл считывается клиентом и посылается серверу с помощью протокола TCP. Сервер его сохраняет. Все происходит на одной машине. Проблема собственно вот в чем: не могу понять - откуда в принятых данных (выводятся на экран) мусор и почему в созданном сервером файле пусто...

Клиент:
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
// Socket_(Client).cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <conio.h>
 
int _tmain(int argc, _TCHAR* argv[])
{
    int rc, size, symbols, y=0, i=0; //проверка соединения, позиция при считывании файла, число считанных символов, счетчик.   
    char bufer[100];//для считывания передаваемого файла
    char buf[100];//для приема сообщений сервера
    WSADATA wsd;
    WSAStartup(0X0101, &wsd);
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
 
    sockaddr_in peer;
    peer.sin_family = AF_INET;
    peer.sin_port   = htons(1200);
    peer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
 
    rc = connect(s,(struct sockaddr*) &peer, sizeof(peer));
    if (rc<0) printf ("error");
 
    FILE *f;
    f = fopen("E:\\for_send.txt","rb");
    while(!feof(f)) //пока не конец файла, передаем частями файл (сколько помещается в буфере)
    {
    symbols=fread(bufer,1,sizeof(bufer),f);
    size=ftell(f);
    printf("read symbols: %d, part: %d, pos: %ld \n",symbols,i,size);
    printf("\n");
    if(symbols!=0)
    send(s,bufer,symbols*sizeof(char),0);
    i++;
    if (y==0) break;
    y = recv(s,buf,sizeof(buf),0);//прием ответа сервера (sizeof(buf) - максимально возможный принятый объем)
    printf("%s\n",buf);
    }
    fclose (f);
    getch();
    shutdown(s, 2);
    WSACleanup();
    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
// Socket.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    int rc, i=0;
    WSADATA wsd;
    WSAStartup(0X0101, &wsd);
    FILE *f;
    f = fopen("E:\\newinfo.txt","wb");
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    
    struct sockaddr_in myCom;
    myCom.sin_family = AF_INET;
    myCom.sin_port   = htons(1200);
    myCom.sin_addr.S_un.S_addr = INADDR_ANY;
 
    rc = bind(s,(struct sockaddr*)&myCom,sizeof(myCom));
    if (rc<0) printf ("error");
    listen(s, 5);
 
    SOCKET s1; 
    if ((s1=accept(s,NULL,NULL))==-1)printf ("error");
 
    while (true)
    {
    char buf[100];
    int r = recv(s1, buf, sizeof(buf), 0);
    if (r == 0)//если нет данных
    {
      cout<<"0 bytes"<<endl;
      return false;
    }
    if (r < 0)
    {
      cout<<"Error: "<<WSAGetLastError()<<endl; //вывод кода ошибки
      return false;
    }
    WriteFile( f, buf, r, NULL, NULL);
    //передача ответа после приема 
    printf("\n%s \n",buf);
    cout<<"receive bytes: "<<r<<", part: "<<i<<endl;
    printf("\n");
    send(s1,"ready",6*sizeof(char),0);
    i++;
    }
    fclose (f);
    getch();
    shutdown(s1, 2);
    WSACleanup();
    return 0;
}
Вложения
Тип файла: rar Desktop.rar (2.58 Мб, 83 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.02.2012, 19:39
Ответы с готовыми решениями:

Передача файла через интернет TCP/IP
Здравствуйте. Проблема следующая: есть клиент (с++) который посылает по частями видео на сервер (с#). При работе на localhost проблем нет,...

TCP-чат (не получается связать сокет через accept)
Никак не получается связать сокет через accept (программа дальше просто не идет). Не пойму почему:( Даже с кодом из учебника почему-то не...

Как только происходит попытка создать сокет для UDP - сокет TCP сразу ломается (выдает 10093).
Добрый день. Пытаюсь сделать соединение, использующее два канала обмена данными - TCP для управления в режиме клмиента, и UDP - для...

6
1080 / 1007 / 107
Регистрация: 28.02.2010
Сообщений: 2,889
12.02.2012, 09:02
Цитата Сообщение от le nom Посмотреть сообщение
почему в созданном сервером файле пусто...
1) WriteFile не работает (см. GetLastError()). Потому-что ему вместо HANDLE, который обычно возвращает CreateFile или OpenFile, ему дается какой-то FILE*. С этим работать не может. Используйте fwrite
2) После записи нужно закрыть файл. В коде это написано, но программа за пределы цикла у меня не выполнялась.

Цитата Сообщение от le nom Посмотреть сообщение
откуда в принятых данных (выводятся на экран) мусор
Это просто печатает buf[100], buf[101], buf[102], buf[103] и т.д. пока не встретится '\0'.
1
4 / 4 / 0
Регистрация: 03.01.2009
Сообщений: 50
12.02.2012, 12:43  [ТС]
Евгений М., с использованием fwrite, к сожалению, мало что поменялась - файл так же пуст. fclose (f) перенесен в цикл, а в передаваемом файле for_send.txt 100 единичек.
Т.е вроде не должен печатать
Цитата Сообщение от Евгений М. Посмотреть сообщение
buf[100], buf[101], buf[102], buf[103] и т.д.
сервер:
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
// Socket.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    int rc, i=0;
    // инициализация библиотеки winsock2
    WSADATA wsd;
    //инициализирует библиотеку ws2_32.dll для приложения. версия windows socket,указатель на структуру
    WSAStartup(0X0101, &wsd);
    FILE *f;
    //инициализация сокета в случае сервера/клиента TCP. Интернет, тип сокета TCP, протокол
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    
    //структура для инициализация сервера
    struct sockaddr_in myCom;
    //используемый домен
    myCom.sin_family = AF_INET;
    //порт для прослушивания
    myCom.sin_port   = htons(1200);
    //адрес привязки порта
    myCom.sin_addr.S_un.S_addr = INADDR_ANY;
 
    //закрепляем порт за приложением. прослушивающий сокет, порт и сетевой интерфейс из структуры, размер
    rc = bind(s,(struct sockaddr*)&myCom,sizeof(myCom));
    if (rc<0) printf ("error");
    //прослушивается сокет
    listen(s, 5);
 
    //принятие соединения, вызов сокета
    SOCKET s1; 
    if ((s1=accept(s,NULL,NULL))==-1)printf ("error");
 
    while (true)//бесконечный цикл
    {
    f = fopen("E:\\newinfo.txt","wb+");//если его нет, перед открытием newinfo.txt создается 
    char buf[100];
    int r = recv(s1, buf, sizeof(buf), 0);//прием файла от клиента. Функция возвращает число считанных байтов 
    if (r == 0)//если нет данных
    {
      cout<<"0 bytes"<<endl;
      return false;//выход из цикла
    }
    if (r < 0)//если recv возвращает -1(ошибка)
    {
      cout<<"Error: "<<WSAGetLastError()<<endl; //вывод кода ошибки
      return false;
    }
    fwrite(buf,(sizeof(buf)/sizeof(char)),r,f);
    //WriteFile(f, buf, r, NULL, NULL);// указатель на файл, буфер, из которого берутся данные, байт для записи, указатель на количество записанных байт 
    //передача ответа после приема 
    printf("\n%s \n",buf);
    cout<<"receive bytes: "<<r<<", part: "<<i<<endl;
    printf("\n");
    send(s1,"ready",6*sizeof(char),0);
    i++;
    fclose (f);
    }
    getch();
    //размыкание соединения
    shutdown(s1, 2);
    //заканчивает использование ws2_32.dll
    WSACleanup();
    return 0;
}
Вложения
Тип файла: rar Desktop.rar (2.65 Мб, 26 просмотров)
0
1080 / 1007 / 107
Регистрация: 28.02.2010
Сообщений: 2,889
12.02.2012, 13:09
Цитата Сообщение от le nom Посмотреть сообщение
Т.е вроде не должен печатать
Все правильно. Печатать не должен. Но printf печатает потому-что он не знает что нужно печатать только 100 символов.

Вы видите пустой файл, потому-что Вы в цикле создаете файл, удалая содержимое ("wb+"). А на самом деле туда все записывалось с успехом. Уже потом все стираете. И цикл застревает скорее всего в этой строке:
C++
1
int r = recv(s1, buf, sizeof(buf), 0)
1
4 / 4 / 0
Регистрация: 03.01.2009
Сообщений: 50
12.02.2012, 17:00  [ТС]
Евгений М., спасибо, теперь записывает
C++
1
f = fopen("E:\\newinfo.txt","ab");
И в записанном файле - тоже лишнее, видно не только в printf дело.
Даже если указать 100 считываемых символов
C++
1
fwrite(buf,100,r,f);
Цитата Сообщение от Евгений М. Посмотреть сообщение
printf печатает потому-что он не знает что нужно печатать только 100 символов
но ведь
C++
1
2
3
char buf[100];
...
printf("\n%s\n",buf);
что-то не могу осознать.
С циклом буду разбираться.
0
1080 / 1007 / 107
Регистрация: 28.02.2010
Сообщений: 2,889
12.02.2012, 20:41
Цитата Сообщение от le nom Посмотреть сообщение
но ведь
Нет. printf не знает что там 100. В данном случае он печатает пока не найдется символ \0.
1
4 / 4 / 0
Регистрация: 03.01.2009
Сообщений: 50
24.02.2012, 12:20  [ТС]
Ежели кому пригодится - рабочая программа

сервер:
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
// Socket.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    int rc, i=1;
    WSADATA wsd;
    WSAStartup(0X0101, &wsd);
    FILE *f;
    //инициализация сокета в случае сервера/клиента TCP. Интернет, тип сокета TCP, протокол
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    
    //структура для инициализация сервера
    struct sockaddr_in myCom;
    myCom.sin_family = AF_INET;
    myCom.sin_port   = htons(1200);
    myCom.sin_addr.S_un.S_addr = INADDR_ANY;
 
    rc = bind(s,(struct sockaddr*)&myCom,sizeof(myCom));
    if (rc<0) printf ("error");
    listen(s, 5);
 
    //принятие соединения, вызов сокета
    SOCKET s1; 
    if ((s1=accept(s,NULL,NULL))==-1)printf ("error");
 
    while (true)
    {
    f = fopen("E:\\newinfo.txt","ab");
    char buf[100];
    int r = recv(s1, buf, sizeof(buf), 0);//прием файла от клиента. Функция возвращает число считанных байтов 
    if (r <= 0)//если нет данных
    {
      cout<<"0 bytes"<<endl;
      cout<<"Error: "<<WSAGetLastError()<<endl; //вывод кода ошибки
      return false;//выход из цикла
    }
    fwrite(buf,1,r,f);
    cout<<"receive bytes: "<<r<<", part: "<<i<<endl;
    printf("\n");
    send(s1,"ready",6*sizeof(char),0);
    i++;
    fclose (f);
    }
    getch();
    //размыкание соединения
    shutdown(s1, 2);
    WSACleanup();
    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
// Socket_(Client).cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>
 
int _tmain(int argc, _TCHAR* argv[])
{
    int rc, size, symbols, y=0, i=1; //проверка соединения, позиция при считывании файла, число считанных символов, счетчик.   
    WSADATA wsd;
    //инициализирует библиотеку для приложения
    WSAStartup(0X0101, &wsd);
    //инициализация сокета в случае сервера/клиента TCP
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
 
    //описание структуры
    sockaddr_in peer;
    peer.sin_family = AF_INET;
    peer.sin_port   = htons(1200);
    peer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
 
    //инициализация клиента
    rc = connect(s,(struct sockaddr*) &peer, sizeof(peer));
    if (rc<0) printf ("error");
 
    FILE *f;
    f = fopen("E:\\for_send.txt","rb");
 
    while(!feof(f)) //пока не конец файла, передаем частями файл (сколько помещается в буфере)
    {
    char bufer[100];
    symbols=fread(bufer,1,100,f);//в буфер один раз считывается 100 бит из файла, возвращает число символов
    size=ftell(f);//функция возвращает текущую позицию
    printf("read symbols: %d, part: %d, pos: %ld \n",symbols,i,size);
    printf("\n");
    send(s,bufer,symbols,0);//передача содержимого буфера
    i++;
    char buf[100];//для приема сообщений сервера
    y = recv(s,buf,sizeof(buf),0);//прием ответа сервера (sizeof(buf) - максимально возможный принятый объем)
    printf("%s\n",buf);
    }
       fclose (f);
    getch();
    // размыкание соединения
    shutdown(s, 2);
    WSACleanup();
    return 0;
}
Вложения
Тип файла: rar Desktop.rar (2.68 Мб, 234 просмотров)
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.02.2012, 12:20
Помогаю со студенческими работами здесь

Передача файла через сокет
Проблема в том что файл восстанавливаемый на клиенте открывается хорошо. На сервере же массив байтов востанавливается, но файл не...

Передача файла через сокет
Итак... у меня сложилась одна затруднительная ситуация. Есть сервер, есть клиент. С передает К файл посредством client.SendFile(filename,...

Передача файла через TCP
Как файл передавать с клиента на сервер я знаю, но мне нужно условие такое &quot;Работа с файлами с помощью байториентированных потоков без...

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

Осуществить подпись SOAP, по стандартам ГИС ГМП, принятого через TCP сокет
Здравствуйте. Требуется осуществить подпись SOAP, по стандартам ГИС ГМП, принятого через тсп сокет. Со второй частью все понятно, а вот с...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru