Форум: "Сети";
Текущий архив: 2003.10.06;
Скачать: [xml.tar.bz2];
ВнизПочему не происходит событие FD_CONNECT? Найти похожие ветки
← →
FireMan_Alexey (2003-08-06 11:35) [0]Такой исходник!
Суть такова, что при выходе в инет, события FD_CONNECT не происходит, хотя в подсети все работает нормально?!!!
Подскажите кто знает!
SocketMessage=WM_USER+$1000;
//Connect
FAddr.sin_addr.S_addr:=inet_addr(PChar(FHost));
If FAddr.sin_addr.S_addr=INADDR_NONE Then
Begin
Host:=GetHostByName(PChar(FHost));
ErrorCode:=WSAGetLastError;
Form1.LB.Items.Add("GetHostByName: "+IntToStr(ErrorCode));
If (ErrorCode<>0)Or(Host=Nil) Then
Begin
Error(Self,ERR_HOSTENT,WSAGetLastError);
Close;
Exit;
End;
CopyMemory(@FAddr.Sin_Addr,@Host.H_Addr_List^[0],Host.h_length);
End;
ErrorCode:=Connect(FSocket,FAddr,Size);
WSAAsyncSelect(FSocket,FHandle,SocketMessage,FD_CLOSE or
FD_READ or
FD_WRITE or
FD_CONNECT);
Procedure WndProc(Var Msg:TMessage);
Begin
//
Case Msg.Msg Of
SocketMessage:
Begin
ErrorCode:=WSAGetSelectError(Msg.LParam);
Form1.LB.Items.Add("Error MSG: "+IntToStr(ErrorCode));
If ErrorCode>WSABASEERR Then
Begin
Error(Self,WSAGetSelectEvent(Msg.LParam),ErrorCode);
Exit;
End;
Case WSAGetSelectEvent(Msg.LParam) Of
FD_READ:Begin
//ShowMessage("FD_READ "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_READ "+IntToStr(FSocket));
Read(Self);
End;
FD_WRITE:Begin
//ShowMessage("FD_WRITE "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_WRITE "+IntToStr(FSocket));
End;
FD_CLOSE:Begin //ShowMessage("FD_CLOSE "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_CLOSE "+IntToStr(FSocket));
Close;
End;
FD_CONNECT:Begin
//ShowMessage("FD_CONNECT "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_CONNECT "+IntToStr(FSocket));
End;
FD_ACCEPT: Begin {ShowMessage("FD_ACCEPT "+IntToStr(FSocket));}
Form1.LB.Items.Add("MSG: FD_Accept "+IntToStr(FSocket));
Accept(Self);
( "Connections: "+IntToStr(FConnections)Такой исходник!
Суть такова, что при выходе в инет, события FD_CONNECT не происходит, хотя в подсети все работает нормально?!!!
Подскажите кто знает!
SocketMessage=WM_USER+$1000;
//Connect
FAddr.sin_addr.S_addr:=inet_addr(PChar(FHost));
If FAddr.sin_addr.S_addr=INADDR_NONE Then
Begin
Host:=GetHostByName(PChar(FHost));
ErrorCode:=WSAGetLastError;
Form1.LB.Items.Add("GetHostByName: "+IntToStr(ErrorCode));
If (ErrorCode<>0)Or(Host=Nil) Then
Begin
Error(Self,ERR_HOSTENT,WSAGetLastError);
Close;
Exit;
End;
CopyMemory(@FAddr.Sin_Addr,@Host.H_Addr_List^[0],Host.h_length);
End;
ErrorCode:=Connect(FSocket,FAddr,Size);
WSAAsyncSelect(FSocket,FHandle,SocketMessage,FD_CLOSE or
FD_READ or
FD_WRITE or
FD_CONNECT);
Procedure WndProc(Var Msg:TMessage);
Begin
//
Case Msg.Msg Of
SocketMessage:
Begin
ErrorCode:=WSAGetSelectError(Msg.LParam);
Form1.LB.Items.Add("Error MSG: "+IntToStr(ErrorCode));
If ErrorCode>WSABASEERR Then
Begin
Error(Self,WSAGetSelectEvent(Msg.LParam),ErrorCode);
Exit;
End;
Case WSAGetSelectEvent(Msg.LParam) Of
FD_READ:Begin
//ShowMessage("FD_READ "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_READ "+IntToStr(FSocket));
Read(Self);
End;
FD_WRITE:Begin
//ShowMessage("FD_WRITE "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_WRITE "+IntToStr(FSocket));
End;
FD_CLOSE:Begin //ShowMessage("FD_CLOSE "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_CLOSE "+IntToStr(FSocket));
Close;
End;
FD_CONNECT:Begin
//ShowMessage("FD_CONNECT "+IntToStr(FSocket));
Form1.LB.Items.Add("MSG: FD_CONNECT "+IntToStr(FSocket));
End;
FD_ACCEPT: Begin {ShowMessage("FD_ACCEPT "+IntToStr(FSocket));}
Form1.LB.Items.Add("MSG: FD_Accept "+IntToStr(FSocket));
Accept(Self);
Form1.LB.Items.Add("Connections: "+IntToStr(FConnections));
end;
End;
End;
End;
← →
Digitman (2003-08-06 12:22) [1]поменяй местами строчки
ErrorCode:=Connect(FSocket,FAddr,Size);
и
WSAAsyncSelect(FSocket,FHandle,SocketMessage,FD_CLOSE or
FD_READ or
FD_WRITE or
FD_CONNECT);
← →
FireMan_Alexey (2003-08-07 11:16) [2]Спасибо!
← →
Digitman (2003-08-07 11:26) [3]
> FireMan_Alexey
заработало и ладно ?
хоть бы поинтересовался, почему именно так, а не иначе)
"грабли" нужно устранять сразу, иначе лупить будут впоследствии с "регулярной завидностью"))
← →
FireMan_Alexey (2003-08-07 11:50) [4]>Digitman
Я как раз хотел спросить об этом!
Я поменял местами и сразу прога перестала коннектиться в инет.
При попытке приконектиться к www.delphimaster.ru
connect выдает -1
а событие FD_CONNECT происходит?
Если можно, объясните пожалуйста как это работает! :-)
← →
Digitman (2003-08-07 12:25) [5]
> Я поменял местами и сразу прога перестала коннектиться в
> инет.
ты просто не дождался события FD_CONNECT
в нижеследующем случае происходит :
1.socket() - создано гнездо, режим по умолчанию - блокирующий, механизм асинхронной нотификации о событиях гнезда не включен
2.connect() - попытка коннекта в синхр.режиме, следующий оператор получит управление только после того, как будет успешно осуществлен коннект (результат = 0) или в нем отказано по каким-то причинам (результат = -1, код причины отказа - результат последующего немедленного вызова ф-ции WSAGetLastError)
3. WSAAsyncSelect() - перевод гнезда в неблокирующий (асинхронный) режим, включаем механизм асинхронной нотификации о событиях гнезда; если коннект уже установлен, событие FD_CONNECT с этого момента не возникнет - в нем попросту нет смысла;
а в этом случае происходит следующее :
1.socket() - создано гнездо, режим по умолчанию - блокирующий, механизм асинхронной нотификации о событиях гнезда не включен
2. WSAAsyncSelect() - перевод гнезда в неблокирующий (асинхронный) режим, включаем механизм асинхронной оконной нотификации о событиях гнезда; коннект еще не установлен.
3.connect() - попытка коннекта в асинхр.режиме, следующий оператор получит управление сразу же.
Следующим оператором нужно проанализировать код возврата ф-ции connect(). Он будет равен -1 (отказ). Тут же анализируем причину вызовом ф-ции WSAGetLastError(). Если он равен WSAEWOULDBLOCK, все в порядке : операция установления коннекта запущена "в фоновом режиме", можно продолжать заниматься "своими делами", о результатах операции будет извещено позже асинхр.оконным сообщением FD_CONNECT. Если он НЕ равен WSAEWOULDBLOCK, операция коннекта не стартована по каким-то конкретным причинам (код причины уже известен), следует закрыть гнездо - ждать FD_CONNECT и прочие события бессмысленно.
После того, как операция по установлению коннекта завершится с тем или иным результатом, гнездо пошлет в указанное окно сообщение FD_CONNECT. Мл.слово параметра сообщения lParam будет содержать константу FD_CONNECT, ст.слово - код отказа (0, если коннект успешен, или иной код причины отказа в коннекте). Параметр wParam укажет хэндл гнезда, пославшего данное сообщение в окно.
← →
FireMan_Alexey (2003-08-07 12:33) [6]У меня получается так:
Если я коннекчусь в синхр.режиме, то ошибки не бывает!
А если, коннекчусь в асинхронном, то обязательно есть какая-то
ошибка!
← →
Digitman (2003-08-07 12:39) [7]
> какая-то
> ошибка
в смысле WSAGetLastError()<> WSAEWOULDBLOCK ? и какая же конкретно ?
← →
FireMan_Alexey (2003-08-07 13:55) [8]Я извиняюсь, если вопросы будут совпадать с прошедшими ответами.
Я сижу за машиной, на которой нет инета.
У меня вопрос:
- Если я оставлю все как есть, и мне понадобятся N сокетов. То каждый коннект такого количества сокетов мне придется ждать N*Время коннекта одного сокета, я так понимаю?
- И если Мне нужно будет ждать по очереди коннект/отказ каждого сокета.
← →
FireMan_Alexey (2003-08-07 13:59) [9]Вот полный код!
Может Я что-то неправильно понял, но при коннекте
выскакивает Мессаг об ошибке!
unit Sockets;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, WinSock, StdCtrls, Spin, ScktComp;
Const
SocketMessage=WM_USER+$1000;
MaxClients =1024;
Err_Startup=-1;
Err_Cleanup=-2;
Err_No_Port=-3;
Err_No_Host=-4;
Err_Open =-5;
Err_Bind =-6;
Err_Listen =-7;
Err_HostEnt=-8;
Err_Accept =-9;
Client=True;
Server=False;
Send_Size=190;
type
TWinSocket= Class;
TOnError = Procedure(Sender:TObject;Socket:TWinSocket;ErrorEvent,Error:Integer) of object;
TOnRead = Procedure(Sender:TObject;Socket:TWinSocket;Var A;Count:Integer) of object;
TOnEvent = Procedure(Sender:TObject;Socket:TWinSocket) of object;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
SE: TSpinEdit;
LB: TListBox;
Button6: TButton;
ServerSocket1: TServerSocket;
procedure Button1Click(Sender: TObject);
Procedure Error_1(Sender:TObject;Socket:TWinSocket;ErrorEvent,Error:Integer);
Procedure Error_2(Sender:TObject;Socket:TWinSocket;ErrorEvent,Error:Integer);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
Procedure Read(Sender:TObject;Socket:TWinSocket;Var A;Count:Integer);
procedure Button6Click(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
TSocketArray=Array of TWinSocket;
TWinSocket = Class
FBuffer :Array [0..4095] of Byte;
FSocket :TSocket;
FConnected :Boolean;
FHandle :HWnd;
FClient :Boolean;
FPort :Word;
FHost :String;
FAddr :TSockAddr;
FSendData :TStream;
FRead :TOnRead;
FWrite :TOnEvent;
FConnect :TOnEvent;
FDisconnect :TOnEvent;
FAccept :TOnEvent;
FError :TOnError;
FMaxWait :Integer;
FConnections:Integer;
FClients :TSocketArray;
FMaxClients :Integer;
FServClient :Boolean;
FServer :TWinSocket;
//-----------------------------
Procedure SetAsyncSelect;
Procedure SendData(Var A;Count:Integer);
Procedure SendStream(Send:TStream;Count:Integer);
Procedure CloseAll;
Procedure Startup;
Procedure Cleanup;
Procedure WndProc(Var Msg:TMessage);
Procedure Open(Client:Boolean);
Procedure Accept(Socket:TWinSocket);
Procedure AllocNewMem(Var T:TSocketArray);
Procedure Close;
Procedure Read;
Procedure Write;
Procedure Error(Socket:TWinSocket;Event,Error:Integer);
( Socket:TSocket) Вот полный код!
Может Я что-то неправильно понял, но при коннекте
выскакивает Мессаг об ошибке!
unit Sockets;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, WinSock, StdCtrls, Spin, ScktComp;
Const
SocketMessage=WM_USER+$1000;
MaxClients =1024;
Err_Startup=-1;
Err_Cleanup=-2;
Err_No_Port=-3;
Err_No_Host=-4;
Err_Open =-5;
Err_Bind =-6;
Err_Listen =-7;
Err_HostEnt=-8;
Err_Accept =-9;
Client=True;
Server=False;
Send_Size=190;
type
TWinSocket= Class;
TOnError = Procedure(Sender:TObject;Socket:TWinSocket;ErrorEvent,Error:Integer) of object;
TOnRead = Procedure(Sender:TObject;Socket:TWinSocket;Var A;Count:Integer) of object;
TOnEvent = Procedure(Sender:TObject;Socket:TWinSocket) of object;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
SE: TSpinEdit;
LB: TListBox;
Button6: TButton;
ServerSocket1: TServerSocket;
procedure Button1Click(Sender: TObject);
Procedure Error_1(Sender:TObject;Socket:TWinSocket;ErrorEvent,Error:Integer);
Procedure Error_2(Sender:TObject;Socket:TWinSocket;ErrorEvent,Error:Integer);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
Procedure Read(Sender:TObject;Socket:TWinSocket;Var A;Count:Integer);
procedure Button6Click(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
TSocketArray=Array of TWinSocket;
TWinSocket = Class
FBuffer :Array [0..4095] of Byte;
FSocket :TSocket;
FConnected :Boolean;
FHandle :HWnd;
FClient :Boolean;
FPort :Word;
FHost :String;
FAddr :TSockAddr;
FSendData :TStream;
FRead :TOnRead;
FWrite :TOnEvent;
FConnect :TOnEvent;
FDisconnect :TOnEvent;
FAccept :TOnEvent;
FError :TOnError;
FMaxWait :Integer;
FConnections:Integer;
FClients :TSocketArray;
FMaxClients :Integer;
FServClient :Boolean;
FServer :TWinSocket;
//-----------------------------
Procedure SetAsyncSelect;
Procedure SendData(Var A;Count:Integer);
Procedure SendStream(Send:TStream;Count:Integer);
Procedure CloseAll;
Procedure Startup;
Procedure Cleanup;
Procedure WndProc(Var Msg:TMessage);
Procedure Open(Client:Boolean);
Procedure Accept(Socket:TWinSocket);
Procedure AllocNewMem(Var T:TSocketArray);
Procedure Close;
Procedure Read;
Procedure Write;
Procedure Error(Socket:TWinSocket;Event,Error:Integer);
Constructor Create(Socket:TSocket);
Destructor Destroy; Override;
End;
var
Form1: TForm1;
T,T1,T2:TWinSocket;
← →
FireMan_Alexey (2003-08-07 14:02) [10]Я отослал код по почте!
← →
Digitman (2003-08-07 14:55) [11]У меня твой код работает.
некорректностей, конечно, немало, но в принципе - логика работает ожидаемо. Ошибок нет, клиент запрашивает коннект к localhost:9600, сервер акцептирует запрос, коннект успешно устанавливается, лог показывает возникновение всех ожидаемых событий обеих сторон (сервера и клиента) в нужной последовательности, без ошибок.
p.s.
окно должно создаваться одно для всех гнезд.
т.е. убери AllocateHWnd()/DeallocateHWnd() из конструктора/деструктора на уровень иниц-ции/деиниц-ции модуля, либо создавай окно только один раз, условно (при создании самого первого гнезда)
нет никакого резона для каждого гнезда создавать отдельное окно.
← →
FireMan_Alexey (2003-08-07 16:08) [12]Огромное спасибо, за то что уделил мне внимание, но вот еще вопрос!
Я не могу определить, почему у меня выскакивает ошибка "0",
когда я коннекчусь к инету!
У меня нет здесь Самих делфей и установить их здесь очень проблематично.
адрес как обычно я использую www.delphimaster.ru :80 и после коннекта или до у меня вылетает месаг. Error FD_CONNECT а ошибка =0 ? :\
Если тебе не очень трудно проверить, то буду очень благодарен!
И еще раз ОГРОМНОЕ СПАСИБО
за помощь!
← →
Digitman (2003-08-07 17:00) [13]
> почему у меня выскакивает ошибка "0
да ты сам этот 0 в лог и пишешь !
а это не ошибка вовсе. это - код успешного завершения вызова ф-ции
← →
Rouse_ (2003-08-07 17:15) [14]>Я не могу определить, почему у меня выскакивает ошибка "0" :))
Млин, ну а хелпы для чего написаны то?
Желаю успехов
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2003.10.06;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.013 c