Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.08.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.039 c
1-1090765611
ctranik
2004-07-25 18:26
2004.08.08
Помогите разобратся с классом


1-1090984252
superedward
2004-07-28 07:10
2004.08.08
ActionManager + ActionMainMenuBar в run-time


3-1089870888
ligor
2004-07-15 09:54
2004.08.08
дата в IB


1-1090833370
Gennadiy
2004-07-26 13:16
2004.08.08
Проблема с меню!!


4-1088177852
djone
2004-06-25 19:37
2004.08.08
Caret





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский