Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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
1-18344
Raptorus
2003-09-25 16:06
2003.10.06
Как можно перекодировать текст из кодировки base64 в Win?


1-18363
Alek Aaz
2003-09-21 12:46
2003.10.06
Не отображаются наследуемые методы и свойства.


1-18365
LLiriK
2003-09-23 06:43
2003.10.06
RichEdit в RunTime


1-18305
dima_shapkin
2003-09-23 11:19
2003.10.06
Такой хитрый грид


1-18393
SH
2003-09-22 15:15
2003.10.06
Сортировка строк





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский