Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

как прочитать файл и передать

10K
30 ноября 2005 года
SN_ok
17 / / 30.11.2005
помогите пожалуйста, не могу понять, на си пишу третий раз.

Пишу программу сервер.
Она должна сделать снимок экрана, и передать файл через сокет.

код следующий:
Код:
#include <vcl.h>
#pragma hdrstop
#include <fstream.h>

#include "Winsock2.h"
#include <jpeg.hpp>
//---------------------------------------------------------------------------

  #define PORT 555
 #define BUF_SIZE 64

  char buf[BUF_SIZE];
  int from_len, err, s_new, sock;
  struct sockaddr_in from_sin;
  struct sockaddr_in sin;
  fstream log_file;
  int symb_len;
  TJPEGImage *l_jpg;
  TImage *l_image;

//---------------------------------------------------------------------------
void main(void) {
  printf("Start server...\r\n");

  // инициализируем процесс библиотеки wsock32.dll, вызвая функцию WSAStartup
  //  0х0101 версия библиотеки которую следует использовать
  WSADATA WsaData;
  err = WSAStartup (0x0101, &WsaData);
  if (err == SOCKET_ERROR){
    printf ("WSAStartup() failed: %ld \r\n", GetLastError ());
    exit;
  };

  // объявляем сокет
  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  // создаем сокет и задаем параметры для сокета
  memset ((char *)&sin, '\0', sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_port = htons(PORT);
  sin.sin_addr.s_addr = INADDR_ANY; //системный вызов привязан к socket'у с локальным адресом

  // связываем сокет с переменной
  err = bind( sock, (struct sockaddr *)&sin, sizeof(sin));
  if (err < 0){
    printf("Bind error.\r\n");
    exit;
  };
  printf("\t Address: %d \r\n", INADDR_ANY);
  printf("\t Port: %d \r\n", PORT);

  // слушаем заданный порт, 3 - кол параллельных подключений
  err = listen (sock, 2);
  if (err < 0){
    printf("Listen error.\r\n");
    exit;
  };

  printf("\t Listen OK. \r\n");
  printf("Server worked!\r\n");

  while (true){
    from_len = sizeof(from_sin);
    s_new = accept(sock, (struct sockaddr*)&from_sin, &from_len);
    if (s_new < 0){
      printf("Accept error.\r\n");
      exit;
    };

    //делаем снимок экрана
    HWND l_hwnd = GetDesktopWindow();
    HDC l_dc = GetDC(l_hwnd);

    l_image = new TImage(NULL);
    l_image->Width = Screen->Width;
    l_image->Height = Screen->Height;
    ::BitBlt(   l_image->Canvas->Handle,
              0, 0, l_image->Width, l_image->Height,
              l_dc, 0, 0, SRCCOPY);

    l_jpg = new TJPEGImage();
    l_jpg->Assign(l_image->Picture->Bitmap);
    l_jpg->SaveToFile("test.jpg");


    //<------ здесь надо прочитать файл test.jpg и послать в сокет ---------->


    char *buff;
    send(s_new, buff, sizeof(buff), 0);


    shutdown (s_new, 0);
    closesocket (s_new);
  };// end while

};


Как прочитать файл test.jpg в двоичном режиме и послать в сокет?
830
01 декабря 2005 года
MVal
76 / / 17.10.2002
Если пишешь на 6-ом билдере и использование чистого API не вопрос идеологии, то проще всего юзать Indy-компанент TIdTCPClient.
Для него будет так:
Код:
IdTCPClient->Host="127.0.0.1";
  IdTCPClient->Port=1234;
  try
   {
    IdTCPClient->Connect();
   } catch(...)
     {
       //Ошибка конекта
     };
    TMemoryStream *Str = new TMemoryStream();
    Str->LoadFromFile("test.jpg");
    Str->Position=0;
    IdTCPClient->WriteStream(Str,false,Str->Size);
    IdTCPClient->Disconnect(); //Если надо.
    delete Str;

Кстате, если будешь что-то подобное использовать - не пиши в файл, сразу сохраняй в Str:
l_jpg->SaveToStream(Str);
Str->Position=0;
Тогда не будет нужды этот файл читать - все и так в памяти.
P.S. Честно признаюсь, что не приходилось использовать эти компаненты для консольных прог. А ГУИ и сервис писал.
10K
01 декабря 2005 года
SN_ok
17 / / 30.11.2005
Цитата:

Если пишешь на 6-ом билдере и использование чистого API не вопрос идеологии, то проще всего юзать Indy-компанент TIdTCPClient.


Спасибо за ответ, да билдер шестой, но как раз идеология разрешает только API.
Компонент возьму на вооружение.

Я поступил так, читаю файл по блокам 1024 и посылаю в сокет.

Код такой:

Код:
// получаем файл jpg
    l_jpg = new TJPEGImage();
    l_jpg->Assign(l_image->Picture->Bitmap);
    l_jpg->SaveToFile("tmp.jpg");

   
    char buff[1025];
    buff[0]=0;
    FILE *df;

    df = fopen("tmp.jpg", "rb");

    while(!feof(df)) {
      memset(buff, 0, 1025);
      //читаем из файла
      fread(buff, 1024, 1, df);
      // посылаем в сокет
      //send(s_new, buff, strlen(buff), 0);
      send(s_new, buff, 1024, 0);
    };

Работает.

Цитата:

Кстате, если будешь что-то подобное использовать - не пиши в файл, сразу сохраняй в Str:
l_jpg->SaveToStream(Str);
Str->Position=0;
Тогда не будет нужды этот файл читать - все и так в памяти.


Догадывался, об этом, но как сделать с потоком не ведаю.

Пробовал сделать так:

Код:
TStream *str;

    l_jpg->SaveToStream(str);
    str->Position=0;

    char buff[1025];
    buff[0]=0;
    int n;
    while( (n=str->Read(buff, 1024))==NULL) {
      memset(buff, 0, 1025);
      send(s_new, buff, 1024, 0);
    };


Прога вылетает.
Как быть с потоком?
1
01 декабря 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by SN_ok
Спасибо за ответ, да билдер шестой, но как раз идеология разрешает только API.
Компонент возьму на вооружение.

Я поступил так, читаю файл по блокам 1024 и посылаю в сокет.

Код такой:
Код:
// получаем файл jpg
    l_jpg = new TJPEGImage();
    l_jpg->Assign(l_image->Picture->Bitmap);
    l_jpg->SaveToFile("tmp.jpg");

   
    char buff[1025];
    buff[0]=0;
    FILE *df;

    df = fopen("tmp.jpg", "rb");

    while(!feof(df)) {
      memset(buff, 0, 1025);
      //читаем из файла
      fread(buff, 1024, 1, df);
      // посылаем в сокет
      //send(s_new, buff, strlen(buff), 0);
      send(s_new, buff, 1024, 0);
    };

Работает.


Догадывался, об этом, но как сделать с потоком не ведаю.

Пробовал сделать так:
Код:
TStream *str;

    l_jpg->SaveToStream(str);
    str->Position=0;

    char buff[1025];
    buff[0]=0;
    int n;
    while( (n=str->Read(buff, 1024))==NULL) {
      memset(buff, 0, 1025);
      send(s_new, buff, 1024, 0);
    };


Прога вылетает.
Как быть с потоком?


Что значит "вылетает" - судя по всему - у тебя str не инициализирован.

10K
03 декабря 2005 года
SN_ok
17 / / 30.11.2005
Кажется, немного разобрался.
Цитата:
судя по всему - у тебя str не инициализирован



Действительно ерунда там.

Подкорректировал, работоспособная программа получилась:

Код:
// получаем jpg
    l_jpg = new TJPEGImage();
    l_jpg->Assign(l_image->Picture->Bitmap);

    TMemoryStream *str = new TMemoryStream();
    l_jpg->SaveToStream(str);
    str->Position=0;
    int sn = str->Size;

    char buff[1025];
    buff[0]=0;

    do {
      memset(buff, 0, 1025);
      str->Read(buff, 1024);
      send(s_new, buff, 1024, 0);
    }while( str->Position<sn );


Спасибо участникам обсуждения.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог