Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> winsock пересылка и исполнение бинарного файла 
:(
    Опции темы
Anbore
Дата 24.11.2016, 04:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 6.6.2014

Репутация: нет
Всего: нет



Всем доброго времени суток.
Имеется сервер и клиент. Нужно с клиента переслать бинарный файл на сервер и исполнить его.
Файл открывается в бинарном режиме, читает в буфер, делает send. Сервер делает recv и из буфера записывает в файл, потом переименовывает.
Пытаюсь переслать и получаю ошибку: "Сделана попытка выполнить операцию на объекте, не являющемся сокетом." 

клиент
Код

#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <locale.h>
#include <string>

#pragma comment(lib, "Ws2_32.lib")

#define PORT 6091

void getError(DWORD errCode)
   {
   char error[1000]; 
   FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 
                 NULL, 
                 WSAGetLastError(), 
                 MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT), 
                 error, sizeof(error), NULL); 
   printf("\nОшибка: %s\n", error); 
   getchar();
   }

int main(int argc, char *argv[])
{

    setlocale(LC_ALL, "Russian");

    WSADATA winsock;
    SOCKET sock;
    if ((WSAStartup(MAKEWORD(2, 0), &winsock))!=NO_ERROR)
    {
        DWORD error = WSAGetLastError();
        getError(error);
        return -1;
    }

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET)
    {
        DWORD error = WSAGetLastError();
        getError(error);
        return -2;
    }

    sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(PORT);

    if (connect(sock, (sockaddr*)&addr, sizeof(addr)) != 0)
    {
        DWORD error = WSAGetLastError();
        getError(error);
        return -3;
    }

    printf("Подключение успешно !\n");
    printf("Посылаю файл .. \n");

    FILE *otpr_file;
    char buff[200];
    memset(buff, 0, 200);
    if ((otpr_file = fopen("D:\\Projects\\server_client\\Debug\\rufus.exe", "rb")) == NULL)
    {
        printf("Ошибка открытия файла.\n");
        return -4;
    }
    else
    {
        for (;;)
        {
            fread(buff, 5, 200, otpr_file);
            int send_chars = send(sock, buff, 200, 0);
            if (send_chars > 0)
            {
                printf("Получено байт: %d\n", send_chars);
            }
            else if (send_chars == 0)
            {
                printf("Соединение закрыто\n");
                break;
            }
            else if (send_chars == SOCKET_ERROR)
            {
                DWORD error = WSAGetLastError();
                getError(error);
                return -5;
                break;
            }
        }
        fclose(otpr_file);
        closesocket(sock);
        WSACleanup();
        return 0;
    }
}


сервер
Код

#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <locale.h>
#include <string>

#pragma comment(lib, "Ws2_32.lib")

#define PORT 6091

void getError(DWORD errCode) 
   {
   char* error; 
   FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
      NULL,
      errCode != 0 ? errCode : WSAGetLastError(),
      MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT),
      error,
      sizeof(error),
      NULL);  
   printf("\nОшибка: %s\n", error); 
   getchar();
   }

int main()
   {
    setlocale(LC_ALL, "Russian");
    
   WSADATA winsock;
   if (FAILED(WSAStartup(MAKEWORD(1, 1), &winsock)))
   {
       DWORD error = WSAGetLastError();
       getError(error);
       return -1;
   }
   SOCKET sock, sub;
   sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if (sock == INVALID_SOCKET)
   {
       DWORD error = WSAGetLastError();
       getError(error);
       return -2;
   }
   sockaddr_in addr;
   
   sockaddr_in incomingAddress;
   int addressLen = sizeof(incomingAddress);
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_port = htons(PORT);
   addr.sin_addr.s_addr = inet_addr("127.0.0.1");
   if (bind(sock, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) 
   {
       DWORD error = WSAGetLastError();
       getError(error);
       return -3;
   }

  if (listen(sock, SOMAXCONN) == SOCKET_ERROR) 
  {
      DWORD error = WSAGetLastError();
       getError(error);
       return -4;
   }
  char buffer[200];
  FILE * prin_file;
  std::string fname = "file" + std::to_string(rand() % 1000) + ".exe";
  char new_name[20];
  memset(new_name, 0, sizeof(fname));
  strncpy(new_name, fname.c_str(), sizeof(new_name) - 1);
  prin_file = fopen(new_name, "wb");
   printf("Ожидание подключения\n");
   for (;;)
   {
       sub = accept(sock, (sockaddr*)&incomingAddress, &addressLen);
       if (sub != INVALID_SOCKET)
       {
           printf("Клиент подключен!\n");
           for (;;) {
               int recv_chars = recv(sub, buffer, 200, 0);
               if (recv_chars > 0)
               {
                   printf("Получено байт: %d\n", recv_chars);
                   fwrite(buffer, 5, 200, prin_file);
               } 
               else if (recv_chars == 0)
               {       
                printf("Соединение закрыто\n");
                
                break;
           }  else if (recv_chars == SOCKET_ERROR)
               {
                   DWORD error = WSAGetLastError();
                   getError(error);
                   return -5;
                   break;
               }
           }    
       } 
   }
   fclose(prin_file);
 
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   memset(&si, 0, sizeof(si));
   memset(&pi, 0, sizeof(si));
   if(!CreateProcess((LPCSTR)prin_file, NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi))
   {
       DWORD error = WSAGetLastError();
       getError(error);
       return -6;
   }
   closesocket(sub);
   closesocket(sock);
   WSACleanup();
   return 0;
}


PM MAIL   Вверх
feodorv
Дата 24.11.2016, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



У Вас в коде замечательно проверяются ошибки, но вот почему-то на fread проверки нет. Хуже того:
Цитата(Anbore @  24.11.2016,  04:30 Найти цитируемый пост)
            fread(buff, 5, 200, otpr_file);

Здесь написано: прочитать из otpr_file в buff 200 блоков по 5 байт (подозреваю, что это просто описка))). Итого запрос на 1000 байт, а буфер даёте на 200 байт. Происходит запись прочитанных из файла данных за пределами буфера. Программа при этом не падает, видимо, ничего жизненно важного для процесса не задето, но вот кислород перекрыт - перезаписывается значение переменной sock, которая теперь хранит не идентификатор сокета, а не известно что.

Добавлено через 3 минуты и 2 секунды
Цитата(Anbore @  24.11.2016,  04:30 Найти цитируемый пост)
                   fwrite(buffer, 5, 200, prin_file);

Тут тоже 5. Значит - не описка?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
vol4ek
Дата 24.11.2016, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


конь в пальто
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 1.5.2011
Где: Минск

Репутация: нет
Всего: 0



добавлю 
Код

FILE * prin_file;
if(!CreateProcess((LPCSTR)prin_file, NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi))


 stdio.h 

Код

typedef struct _iobuf
{
    char*    _ptr;
    int    _cnt;
    char*    _base;
    int    _flag;
    int    _file;
    int    _charbuf;
    int    _bufsiz;
    char*    _tmpfname;
} FILE;


Anbore, открыл недокументированный способ выдирания нужной строки из структуры силой мысли видимо. (LPCSTR)prin_file =) опа, и нет проблем. берите на заметку друзья, много кому понадобится.
PM MAIL ICQ   Вверх
Aoizora
Дата 8.12.2016, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.11.2016

Репутация: нет
Всего: нет



Лол, прикольно. Тоже когда-то абузил размещение полей структур после прочтения книжки Эриксона, но такие вещи зависят от текущей имплементации библиотеки.
PM MAIL   Вверх
_zorn_
Дата 8.12.2016, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: нет
Всего: 12



О чувак, сокеты это такая забавная штука. Вот кажется все должно работать как ты думаешь, а хрен тебе. Ну например recv в лёгкую повесит все приложение если в сокете нет ничего.
send наверное тоже хз. 
Короче select тебе в помощь smile

ЗЫ. Там реально неадекваты это все делали. Ну нечего читать - верни ты управление.
ЗЫЫ. Это про винду

Это сообщение отредактировал(а) _zorn_ - 8.12.2016, 21:49
PM MAIL   Вверх
Aoizora
Дата 8.12.2016, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.11.2016

Репутация: нет
Всего: нет



Можно же просто в отдельном потоке запустить чтение и обработку.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1254 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.