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

Вниз

Socket Messages   Найти похожие ветки 

 
P@vel   (2004-06-17 18:36) [0]

Когда сокет посылает сообщение о каких либо переменах, где и какая информация содержится. Понятно что тип сообщение FD_READ это сигнал о готовности чтения. Но не плохо было бы получить и дескриптор сокета виновника. Может мои глаза уже совсем не видят но в инфе я этого не нашёл.


 
Verg ©   (2004-06-17 20:23) [1]

When one of the nominated network events occurs on the specified socket s, the application"s window hWnd receives message wMsg. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in Winsock2.h.

Это ничего, что я цитирую MSDN ?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsaasyncselect_2.asp


 
P@vel   (2004-06-17 20:28) [2]

Sorry. Наверное периседел за компом.


 
P@vel   (2004-06-17 22:58) [3]

Так следкющая проблема. Когда клиент подключается. Мою процедуру обработки начинает заваливать сообщениями о попытке подключения. Хотя на стороне клиента подключение происходит 1 раз. (это 100%).

procedure TServer.WndProc(var Msg: TMessage);
begin
 if Msg.Msg= 0 then
 begin
   if Msg.LParamLo = FD_ACCEPT then
   begin
     Client:=Accept(LSocket,@Clientinfo,@ClientSize);
     if Client <> SOCKET_ERROR then
     begin
       SocketList.Add(@Client);
       ClientCount:=SocketList.Count;
     end;
   end;
 end;
end;


Как исправить ситуацию?


 
Verg ©   (2004-06-17 23:36) [4]


> if Msg.Msg= 0 then


????


 
P@vel   (2004-06-18 00:22) [5]

:) экспериментально было доказано что все сообщения относящиеся к сокету имеют. MSG = 0 (X3 почему).  Но всётаки почему пока клиент конектилса с ошибками, такое собщение приходило 1 раз, а сейчас их 1000 за секунду.


 
Digitman ©   (2004-06-18 08:12) [6]


> экспериментально было доказано что все сообщения относящиеся
> к сокету имеют. MSG = 0


ничего подобного


> пока клиент конектилса с ошибками


это как ?


> сейчас их 1000 за секунду.


склонен предположить, что это вызвано как раз твоим "экспериментальным доказательством" -

условие
 if Msg.Msg= 0 then..

не выполняется, значит не выполняется и Accept(), и кл.запрос на акцепт продолжает "висеть", возбуждая раз за разом FD_ACCEPT


 
P@vel   (2004-06-18 10:57) [7]

Нет понимаете, я делаю трассировку и из нее видно, что msg =0. условия выполняются нормально. И ацепт срабатывает. Кстати отсюда

SocketList.Add(@Client);
ClientCount:=SocketList.Count;

я и увидел, что число соединений растёт с бешаной скоростью.

Приведу код клиента чтобы не говорили, что я там в цикле посилаю запросы.



Constructor TClient.Create;
begin
 inherited Create;
 InWin:=AllocateHWnd(WndProc);
 SetLength(Messages,1);
 WsaStartup(makeword(2,2),Wsadata);
 LSocket:=Socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
 ClientInfo.sin_port:=htons(2685);
 ClientInfo.sin_addr.S_addr:=inet_addr(PChar("127.0.0.1"));
 ClientInfo.sin_family:=PF_INET;
 Error:=WSAAsyncSelect(LSocket,InWIn,Msg.Msg,FD_READ or FD_WRITE or FD_ACCEPT or FD_CONNECT);
 Error:=connect(LSocket, @Clientinfo, SizeOf(Clientinfo));
 LastError:=WsaGetLastError;
end;


и Сервер


Constructor TServer.Create;
begin
 inherited Create;
 SocketList:=Tlist.Create;
 InWin:=AllocateHWnd(WndProc);
 WsaStartup(makeword(2,2),Wsadata);
 LSocket:=Socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
 BindName.sin_port:=htons(2685);
 BindName.sin_family:=AF_INET;
 BindName.sin_addr.S_addr:=htonl(INADDR_ANY);
 bind(LSocket,@BindName,SizeOf(BindName));
 WSAGetLastError;
 Listen(LSocket,5);
 WSAAsyncSelect(LSocket,InWIn,Msg.Msg,FD_READ or FD_WRITE or FD_ACCEPT or FD_CONNECT or FD_CLOSE);
 LastError:=WsaGetLastError;
end;


 
Digitman ©   (2004-06-18 11:16) [8]

что такое Msg.Msg ? где и как объявлено ? чему равно при вызове WSAAsyncSelect ?
зачем серверу FD_CONNECT ?
зачем клиенту FD_ACCEPT ?


 
P@vel   (2004-06-18 11:57) [9]


> что такое Msg.Msg ?

Msg:Tmessage;
Нечиму не равно как объявил так и засунул. Вероятно = 0 т.к в объектах все перем. инициализируются нулями(В отличии от глобальных). Или стоит указать явно?.


> зачем серверу FD_CONNECT ?
> зачем клиенту FD_ACCEPT ?

Это побочный эффект возникший в следствии создания одного объекта из другого путём копирования. :) Сейчас уберу.


 
Digitman ©   (2004-06-18 12:08) [10]


> Нечиму не равно как объявил так и засунул. Вероятно = 0


MSG = 0 (X3 почему).  


вот именно потому


 
P@vel   (2004-06-18 12:21) [11]

Ну это в принципе не важно будь дескриптор хоть 4563 всё равно эта бадяга продолжается. Кстати у сокета клиента возникает ошибка 10035 при попытке соединения. Но я вычитал, что для асинхронных сокетов это нормально.


 
Digitman ©   (2004-06-18 12:44) [12]

For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-triggered." This means that if the re-enabling routine is called and the relevant condition is still met after the call, a WSAAsyncSelect message is posted to the application. This allows an application to be event-driven and not be concerned with the amount of data that arrives at any one time


 
psb   (2004-06-18 15:05) [13]

кто мне может помочь? ....
мне нужно в winsock создать сокет для работы с SPX, и осуществить ссответственно работу, т.е. пересыл нескольких  сообщений по этому протоколу между машинами ..
очень нужно ......


 
P@vel   (2004-06-18 15:27) [14]


> Digitman

Я не немогу понять выше написаное.  

This means that if the re-enabling routine is called and the relevant condition is still met after the call, a WSAAsyncSelect message is posted to the application Пожалуйста обясни по русски если не сложно.


 
Digitman ©   (2004-06-18 16:30) [15]


> P@vel   (18.06.04 15:27) [14]


ты в состоянии привести полный код класса TServer ?


 
P@vel   (2004-06-18 21:45) [16]


type
 TServer = class(TObject)
 private
   InWin:HWND;{Handle okna priemnika soobshenij}
   Client:TSocket;{Identifier soketa klienta zhdushego obrabotki}
   ClientSize:integer;{razmer dannih soketa klienta zhdushego soedinenija}
   Bindname:sockaddr;{Informasija o proslushivajushem sokete}
   WsaData:TwsaData;{Infa o sokete}
   procedure WndProc(var Msg: TMessage);

 public
   ClientCount:integer; {koli4estvo podsoedinivshihsa klientov}
   ClientInfo:sockaddr;{Informacija o kliente pitajushemsa podsoedinitsa}
   Msg:Tmessage;{Soobshenie posilaemoe pri podklu4enii}
   CurrentAdress:string; {Tekushij Setevoj adres}
   Error:integer; {oshibka }
   LSocket:Tsocket; {Deskriptor proslushivaemogo soketa}
   LastError:integer;{Kod poslednej oshibki}
   Constructor Create;
   Destructor Destroy;
end;

procedure TServer.WndProc(var Msg: TMessage);
begin
 if Msg.Msg= 5963 then
 begin
   if Msg.LParamLo = FD_ACCEPT then
   begin
     Client:=Accept(LSocket,@Clientinfo,@ClientSize);
     if Client <> SOCKET_ERROR then
     begin
       SocketList.Add(@Client);
       ClientCount:=SocketList.Count;
       LastError:=msg.LParamHi;
     end;
   end;
   if Msg.LParamLo = FD_CLOSE then
   begin
     SocketList.Delete(FindPos(msg.WParam));
   end;
 end;
end;

Constructor TServer.Create;
begin
 inherited Create;
 SocketList:=Tlist.Create;
 InWin:=AllocateHWnd(WndProc);
 WsaStartup(makeword(2,2),Wsadata);
 LSocket:=Socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
 BindName.sin_port:=htons(2685);
 BindName.sin_family:=AF_INET;
 BindName.sin_addr.S_addr:=htonl(INADDR_ANY);
 bind(LSocket,@BindName,SizeOf(BindName));
 WSAGetLastError;
 Listen(LSocket,5);
 WSAAsyncSelect(LSocket,InWIn,5963,FD_READ or FD_WRITE or FD_ACCEPT or FD_CLOSE);
 LastError:=WsaGetLastError;
end;

Destructor TServer.Destroy;
begin
 inherited Destroy;
 WsaCleanup;
 DeallocateHWnd(InWin);
 SocketList.Destroy;
end;


 
Digitman ©   (2004-06-21 11:43) [17]

примерно так это должно выглядеть :

const
 CM_SOCKETMESSAGE = 5963;

type
 PClientInfo = ^TClientInfo;
 TClientInfo = packed record
   hSocket: THandle;
   Address: DWord;
   Port: DWord;    
 end;

 TCMSocketMessage = record
   Msg: Cardinal;
   Socket: THandle;
   SelectEvent: Word;
   SelectError: Word;
   Result: Longint;
 end;

TServer = class(TObject)
private
  procedure CMSocketMessage(var Message: TCMSocketMessage); message CM_SOCKETMESSAGE;
  InWin:HWND;{Handle okna priemnika soobshenij}
  Bindname:sockaddr;{Informasija o proslushivajushem sokete}
  WsaData:TwsaData;{Infa o sokete}
  procedure WndProc(var Msg: TMessage);
protected
  procedure DoAccept(Socket: THandle);
  procedure DoClose(Socket: THandle);
  ..
public
  CurrentAdress:string; {Tekushij Setevoj adres}
  LSocket:Tsocket; {Deskriptor proslushivaemogo soketa}
  Constructor Create;
  Destructor Destroy; override;
  property ClientCount: integer read Get_ClientCount;
end;

procedure CheckWSResult(Value: Boolean; Op: String);
var
 Err: DWord;
begin
 if not Value then
   begin
     Err := WSAGetLasterror;
     if Err <> WSAEWOULDBLOCK then
       raise Exception.Create("Function " + Op + " fails with error code = " + IntToStr(Err));
   end;
end;

procedure TServer.WndProc(var Msg: TMessage);
begin
Dispatch(Msg.Message);
end;

Constructor TServer.Create;
begin
inherited Create;
WsaStartup(makeword(2,2),Wsadata);
LSocket:=Socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
CheckWSResult(LSocket <> INVALID_SOCKET, "Socket()");
BindName.sin_port:=htons(2685);
BindName.sin_family:=AF_INET;
BindName.sin_addr.S_addr:=htonl(INADDR_ANY);
CheckWSResult(bind(LSocket,@BindName,SizeOf(BindName)) = 0, "bind()");
SocketList:=Tlist.Create;
InWin:=AllocateHWnd(WndProc);
CheckWSResult(WSAAsyncSelect(LSocket,InWIn,CM_SOCKETMESSAGE, FD_ACCEPT) = 0, "WSAAsyncSelect()");
CheckWSResult(Listen(LSocket,5) = 0, "listen()");
end;

Destructor TServer.Destroy;
var i: Integer;
   ci: PClientInfo;
begin
CloseSocket(LSocket);
for i := 0 to SocketList.Count - 1 do
  begin
    ci := PClientInfo(SocketList[i]);
    CloseSocket(ci.hSocket);
    Dispose(ci);
  end;
DeallocateHWnd(InWin);
SocketList.Free;
inherited Destroy;
WsaCleanup;
end;

procedure TServer.CMSocketMessage(var Message: TCMSocketMessage);

 function CheckError: Boolean;
 var
   ErrorEvent: String;
   ErrorCode: Integer;
 begin
   if Message.SelectError <> 0 then
   begin
     Result := False;
     ErrorCode := Message.SelectError;
     case Message.SelectEvent of
       FD_CLOSE: ErrorEvent := "Disconnect";
       FD_READ: ErrorEvent := "Receive";
       FD_WRITE: ErrorEvent := "Send";
       FD_ACCEPT: ErrorEvent := "Accept";
     else
       ErrorEvent := "General";
     end;
     if ErrorCode <> 0 then
      begin  
       LastError := ErrorCode;
       raise Exception.Create(ErrorEvent + " error with code = " +  IntToStr(ErrorCode));
      end;
   end else Result := True;
 end;

begin
 with Message do
   if CheckError then
     case SelectEvent of
       FD_CONNECT: DoConnect(Socket);
       FD_CLOSE: DoDisconnect(Socket);
       FD_READ: DoRead(Socket);
       FD_WRITE: DoWrite(Socket);
       FD_ACCEPT: DoAccept(Socket);
     end;
end;

procedure TServer.DoAccept(Socket);
var
 hClient: THandle;
 ClientInfo: TSockAddr;
 ClientSize: Integer;
 ClientData: PClientInfo;
begin
 hClient:=Accept(LSocket,@Clientinfo,@ClientSize);
 try
   CheckWSError(Client <> SOCKET_ERROR)
   CheckWSResult(WSAAsyncSelect(hClient,InWIn,CM_SOCKETMESSAGE, FD_READ or FD_WRITE or FD_CLOSE) = 0, "WSAAsyncSelect()");  
   New(ClientData);
   ClientData.hSocket := hClient;
   ClientData.Address := ntohl(Clientinfo.sin_addr.S_addr);
   ClientData.Port := ntohs(Clientinfo.sin_port);
   SocketList.Add(ClientData);
 except
   on e: Exception do
   ShowNessage(e.message);
 end;
end;

procedure TServer.DoClose(Socket);
var
 i: Integer;
 ci: PClientInfo;
begin
CloseHandle(Socket);
for i := 0 to SocketList.Count - 1 do
  begin
    ci := PClientInfo(SocketList[i]);
    if ci.hSocket = Socket then
      begin
       Dispose(ci);
       Delete(i);
       break;
      end;
  end;
end;

procedure TServer.Get_ClientCount;
begin
 Result := SocketList.Count;
end;


 
AngelOKES   (2004-06-22 08:00) [18]

Помогит если можете.
Как серверу-сокету определить по какому IP адресу заходит клиент-сокет.



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

Форум: "Сети";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.031 c
3-1090921050
Artjom
2004-07-27 13:37
2004.08.22
Изменение структуры таблицы


3-1091042715
GanibalLector
2004-07-28 23:25
2004.08.22
зависание приложения при выполнении запроса


14-1091513884
Narat
2004-08-03 10:18
2004.08.22
RX components for Delphi 8


3-1090840517
chirchik
2004-07-26 15:15
2004.08.22
TForm.FormActivate - долгая загрузка


1-1091660520
shine
2004-08-05 03:02
2004.08.22
Копирование колекций.Ошибка при assign.





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