Форум: "Сети";
Текущий архив: 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