Форум: "Сети";
Текущий архив: 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.51 MB
Время: 0.04 c