Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.08;
Скачать: CL | DM;

Вниз

Именованные каналы   Найти похожие ветки 

 
LuceSolare   (2004-05-23 11:33) [0]

Всем привет!
У меня такая проблема - я написала клиент и сервер для пересылки файлов с использованием именованных каналов. Всё работает просто обалденно, но почему-то только на локальной машине. Когда я попробовала провести полевые испытания в нормальной сети у нас на кафедре, клиент начал жаловаться - нет доступа. В чём здесь проблема и как её решить обойдя администратора нашей сети( если это связано с правами пользователей).


 
имя   (2004-05-23 18:53) [1]

Удалено модератором


 
Polevi ©   (2004-05-23 19:13) [2]

Named Pipes
на сайте есть статья Игоря Шевченко


 
LuceSolare   (2004-05-23 23:01) [3]

Удалено модератором


 
LuceSolare   (2004-05-23 23:14) [4]

А теперь я ещё проверила "в поле" ту же программу, но с использованием сокетов. тоже не может соединиться. Сервер, бедный, находится всё время в ждущем состоянии, а клиент ,  пытаясь пробиться к серверу, выдаёт ошибку - таймаут (10061 вроде бы).
Вот. А ещё моя прога-клиент с именованными каналами не присоединяется к серверу, если указывать IP.


 
Fay ©   (2004-05-24 06:30) [5]

Код давай


 
Evgeny V ©   (2004-05-24 06:53) [6]

Без кода трудно что сказать, еще раз внимательно почитай статью Шевченко, статья хорошая, обрати внимание на правильность задания имени именованного канала  \\Сервер\Pipe\[путь]имя - где Сервер - имя сервера (если \\.\ локальный сервер), на котором создан канал, Pipe - обязательная строка, уведомляющая систему о принадлежности к NPFS, [путь] - необязательный параметр, может содержать имя каталога, имя - уникальное имя пайпа. Сокеты - тоже надо код посмотреть, что и как ты делаешь.


 
LuceSolare   (2004-05-25 21:37) [7]

Ниже я вставила листинги клиента и сервера.
Задание было такое - написать пересылку файлов с использованием именованных каналов (сокеты, кстати, уже заработали Ж:-)  ).

Написано на билдере. Не удивляйтесь моей работе со строками, просто в билдере у меня с AnsiString всё работало очень криво, приходилось изобретать очевидную чушь, иначе он писал в строки своё.

Клиент может записывать файлы на сервер и загружать их с сервера,
поэтому в обоих программах по два куска очень похожего кода пересылки в именованный канал файла и чтения файла из канала.

Работает всё так: В клиенте указываются пути к файлам на локальной машине и на сервере, если был выбран режим загрузки с сервера, вызывается процедура DoWork с параметром r (read), иначе с w.

В этой процедуре происходит следующее:
  Из двух путей к файлам формируется одна строка, пути разделяются *, в начале пишется переданный параметр работы. Эта строка отсылается серверу. Он её разделяет на два пути, выделяет режим и в зависимости от режима выполняет нужный код.

(Только что подумала, зачем серверу путь к файлу на клиенте, он всё равно с его файлами не работает, надо будет исправить)


 
LuceSolare   (2004-05-25 21:37) [8]

Сервер


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "windows.h"
#include "server2.h"
#include "strutils.hpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
bool t=true;
bool y=True;

  VOID InstanceThread(LPVOID);
  BOOL fConnected;
  DWORD dwThreadId;
  HANDLE hPipe, hThread;
  LPTSTR lpszPipename = "\\\\.\\pipe\\port69";
  DWORD BUFSIZE=512;
  DWORD PIPE_TIMEOUT=20000;
  int xx = 0;

// процедура обслуживает подсоединившегося клиента

VOID InstanceThread(LPVOID lpvParam)
{//HANDLE hMutex;
  int pos, mb;
  char* Pos;
  char p;
  CHAR chRequest[512];
  CHAR chReply[512];
  AnsiString S_path, C_path, St;
  DWORD cbBytesRead, cbWritten;
  BOOL fSuccess;
  HANDLE hPipe,  hFile;
  DWORD size, position;
// был передан при создании нити
  hPipe = (HANDLE) lpvParam;

// Читаем запросы клиента
  while (1)
  { fSuccess = ReadFile(hPipe,chRequest,BUFSIZE,&cbBytesRead,NULL);
     if (! fSuccess || cbBytesRead == 0)
         {ShowMessage("не могу прочесть...");return;}
      else  break;
  }
// разделение путей

               Pos=chRequest;
               for(int i=0; i<StrLen(Pos); i++){if(Pos[i]=="*") {pos=i;break;}}
               St = (AnsiString) Pos;
               S_path = St.SubString(2, pos-1);
               p = Pos[0];
               C_path=RightStr((AnsiString) Pos, StrLen(Pos)-pos-1);
               switch (p){
               // идёт блок чтения из файла и записи в канал
                  case "r":{
                               hFile=CreateFile(S_path.c_str(),GENERIC_READ|GENERIC_WRITE, 0,NULL, OPEN_EXISTING, 0, NULL);

                               if(hFile!=INVALID_HANDLE_VALUE){

                               do{
                                       fSuccess = ReadFile(hFile,chRequest,BUFSIZE,&cbBytesRead,NULL);
                                       fSuccess = WriteFile(hPipe, chRequest,cbBytesRead, &cbWritten,NULL);
                                       FlushFileBuffers(hPipe);

                                }while(!(fSuccess && cbBytesRead==0));
                                }
                                 CloseHandle(hFile);
                                 DisconnectNamedPipe(hPipe);
                                 CloseHandle(hPipe);
                                break;
                               }
                  case "w":{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                               hFile=CreateFile(S_path.c_str(),GENERIC_WRITE,0,NULL,CREATE_NEW,0,NULL);

                               if(GetLastError()==80)
                                { mb=Application->MessageBox("Файл уже существует. \n Перезаписать?", "Файл уже есть!", MB_YESNO);
                                  if (mb==IDYES)
                                         hFile=CreateFile(S_path.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
                                  else {
                                        ShowMessage("Операция чтения с сервера не будет завершена.");
                                        DeleteFile(S_path);
                                        CloseHandle(hFile);
                                        DisconnectNamedPipe(hPipe);
                                        CloseHandle(hPipe);
                                        return;
                                        }
                                }
                               do {  fSuccess = ReadFile(hPipe,chRequest,512,&cbBytesRead,NULL);

                                     if (!fSuccess)ShowMessage(GetLastError());

                                     fSuccess = WriteFile(hFile, chRequest, cbBytesRead,&cbWritten, NULL);

                                     if (!fSuccess)ShowMessage(GetLastError());

                                }while (!(fSuccess && cbBytesRead == 0));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                                 CloseHandle(hFile);
                                 DisconnectNamedPipe(hPipe);
                                 CloseHandle(hPipe);
                               break;
                            }

              }
}
// процедура выполняет бесконечный цикл по созданию канала и обслуживанию клиента
void DoWork()
{while(t){
while (y)
  { hPipe = CreateNamedPipe(
         lpszPipename,             // pipe name
         PIPE_ACCESS_DUPLEX,       // read/write access
         PIPE_TYPE_MESSAGE |       // message type pipe
         PIPE_READMODE_MESSAGE |   // message-read mode
         PIPE_WAIT,                // blocking mode
         10,                       // max. instances
         BUFSIZE,                  // output buffer size
         BUFSIZE,                  // input buffer size
         PIPE_TIMEOUT,             // client time-out
         NULL);                    // no security attribute

     if (hPipe == INVALID_HANDLE_VALUE) {ShowMessage(GetLastError());}
        else {y=False;}//ShowMessage("Канал создан");
  }
     fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
     if (fConnected){ hThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) InstanceThread,(LPVOID) hPipe,0,&dwThreadId);
     if (hThread == NULL) ShowMessage("CreateThread error");  else   {CloseHandle(hThread);y=True;}
      }
}
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 DoWork();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 CloseHandle(hPipe);
 t=false;
}
//---------------------------------------------------------------------------



 
LuceSolare   (2004-05-25 21:38) [9]

Клиент


#include <vcl.h>
#pragma hdrstop
//#include "string.h"
#include "windows.h"
#include "np_client.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tclient *client;
  HANDLE hPipe;
  const char* lpvMessage;
  CHAR chBuf[512];
  BOOL fSuccess;
  DWORD cbRead, cbWritten, dwMode;
  LPTSTR lpszPipename;
  char * Msg = new char[50];
  char* SN = new char[50];
//   char* text = new char[50];
  char* localpath = new char[50];
  const char* ptext="\\pipe\\port69";
  const char* ptext1="\\\\";
//---------------------------------------------------------------------------
__fastcall Tclient::Tclient(TComponent* Owner): TForm(Owner)
{
}
//---------------------------------------------------------------------------
void doOperation(char* oper)
{ int mb;
  StrCopy(localpath, "");
  StrCat(localpath, client->onlocal->Text.c_str());
  StrCopy(Msg,"");
  StrCopy(Msg,oper);
  StrCat(Msg,client->onserver->Text.c_str());
  StrCat(Msg, "*");
  StrCat(Msg,client->onlocal->Text.c_str());
  lpvMessage=Msg;
  HANDLE hFile;
 
  fSuccess = WriteFile(hPipe,lpvMessage,strlen(lpvMessage) + 1,&cbWritten,NULL);
  if (! fSuccess) ShowMessage("Не могу отправить запрос серверу");
 
  switch (oper[0]){
   case "r":{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              hFile=CreateFile(localpath,GENERIC_WRITE,0,NULL,CREATE_NEW,0,NULL);

              if(GetLastError()==80)
               { mb=Application->MessageBox("Файл уже существует. \n Перезаписать?", "Файл уже есть!", MB_YESNO);
                 if (mb==IDYES)
                        hFile=CreateFile(localpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
                 else {
                       ShowMessage("Операция чтения с сервера не будет завершена.");
                       DeleteFile(localpath);
                       CloseHandle(hFile);
                       CloseHandle(hPipe);
                       return;
                       }
               }
              do {  fSuccess = ReadFile(hPipe,chBuf,512,&cbRead,NULL);

                    if (!fSuccess)ShowMessage(GetLastError());

                    fSuccess = WriteFile(hFile, chBuf, cbRead,&cbWritten, NULL);

                    if (!fSuccess)ShowMessage(GetLastError());

               }while (!(fSuccess && cbRead == 0));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             CloseHandle(hFile);
             CloseHandle(hPipe);

             break;
             }
   case "w":{
             hFile=CreateFile(localpath,GENERIC_READ|GENERIC_WRITE, 0,NULL, OPEN_EXISTING, 0, NULL);

             if(hFile!=INVALID_HANDLE_VALUE){

                do{
                    fSuccess = ReadFile(hFile,chBuf,512,&cbRead,NULL);
                    fSuccess = WriteFile(hPipe, chBuf,cbRead, &cbWritten,NULL);
                    FlushFileBuffers(hPipe);

                 }while(!(fSuccess && cbRead==0));
                }
                else {ShowMessage(GetLastError());CloseHandle(hPipe);}
              ShowMessage("Операция завершена.");
              CloseHandle(hFile);
              CloseHandle(hPipe);

             break;
            }
  }
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void __fastcall Tclient::goClick(TObject *Sender)
{
 StrCopy(SN, "");
 StrCat(SN, ptext1);
 StrCat(SN,sname->Text.c_str());
 StrCat(SN, ptext);
 lpszPipename=SN;
 hPipe = CreateFile(lpszPipename, GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
// Удалось подсоединиться к каналу!  Ж:-)
   if (hPipe != INVALID_HANDLE_VALUE) {
       if (fs->Checked) doOperation("r");
       else doOperation("w");
   }
// Но так везёт не всегда...И на этот случай код ниже:
        else{ if (GetLastError() != ERROR_PIPE_BUSY) {ShowMessage(GetLastError());}//ShowMessage(GetLastError());y=False;
                  else
                       if (!WaitNamedPipe(lpszPipename, 20000) )
                              ShowMessage("The pipe was busy longer than 20 seconds\n Try another time.");}//y=False;
}


 
Evgeny V ©   (2004-05-26 07:29) [10]

Код посмотрю внимательней чуть позже, сразу увы найти недочеты трудно, но то что увидел или услышал - Про AnsiString - класс реализован хорошо, у меня с ним проблем не было. Про сервер  - в цикле ты создаешь экземпляры канала, в DoWork, наверное имеет смысл проверять сколько создано каналов на данный момент, что бы не получать if (hPipe == INVALID_HANDLE_VALUE) {ShowMessage(GetLastError());} Ты указала 10 экземпляров канала можно создать, а если они уже созданы и сконекчены? Ты еще попытаешься создать экземпляр, и будешь его создавать в цикле пока или не освободится какой-либо созданный канал или если этого не будет, то всегда. Про клиент рекомендую сперва
WaitNamedPipe(lpszPipename, 20000), и в случае успеха только тогда уже  hPipe = CreateFile(lpszPipename, GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATRIBUTE_NORMAL,NULL);


 
LuceSolare   (2004-06-04 20:02) [11]

Ну не знаю...Процесс создания каналов сервером я взяла из МСДНа.Предполагалось, что он будет обслуживать несколько клиентов, но фактически сервер выходит из цикла после первого же удачно созданного канала и потом ждёт подсоединения клиента, поэтому клиент не может присоединиться к уже соединённому каналу. Тем более, я всегда проверяла работу программы только с одним клиентом, больше к каналу подсоединяться некому.
     А вот насчёт WaitNamedPipe идея хорошая, но ведь я могу просто раскомментарить ShowMessage("Канал создан") и только после этого сообщения запускать клиента - т.е. канал будет, а клиент не подсоединится.


 
Fay ©   (2004-06-04 23:17) [12]

Замените PIPE_WAIT на PIPE_NOWAIT.
Зависает?



Страницы: 1 вся ветка

Текущий архив: 2004.08.08;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.025 c
6-1086278285
Micah'GF
2004-06-03 19:58
2004.08.08
WinSock: глючит recvfrom


14-1090618605
lak
2004-07-24 01:36
2004.08.08
МеГаРеСпЕкТ


4-1088091605
Dextor
2004-06-24 19:40
2004.08.08
PopupMenu WINDOWS


9-1078418351
Unknown user
2004-03-04 19:39
2004.08.08
Оцените возможности следующей версии моего OpenGL движка.


6-1086678438
leonidus
2004-06-08 11:07
2004.08.08
Вопрос по TWebBrowser