クライアント:
//is called when the client tries to log in
procedure TLogin_Form.btnLoginClick(Sender: TObject);
var LoginQuery: TQuery;
begin
//If socket not open, open it
if not LoginSocket.Active then
begin
LoginSocket.Open;
end;
//create package
LoginQuery.Login := ledtName.Text;
LoginQuery.Passwort := ledtPasswort.Text;
LoginQuery.IP := LoginSocket.Socket.LocalAddress;
//send package
LoginSocket.Socket.SendBuf(LoginQuery, SizeOf(LoginQuery));
end;
サーバ:
//This procedure is executed when I click on start server button
procedure TServer_Form.btnStartStopClick(Sender: TObject);
begin
//If not open, open it
if not ServerSocket.Active then
begin
btnStartStop.Caption := 'stop server';
//Open ServerSocket
ServerSocket.Open;
end
else
begin
//If Socket open, close it, but watch for active connctions.
if ServerSocket.Socket.ActiveConnections > 0 then
begin
ShowMessage('Clients still logged in');
end
else
begin
//If no clients connected, close socket
ServerSocket.Close;
end;
end;
end;
//This procedure is called to verify weather the user is logged in and to send the verification back
procedure UserCheckExist(Login, Passwort: string);
var LoginReply: TReply;
begin
begin
//Connect to DB
DBConnect(true);
DM.AQ_LOGIN.Close;
DM.AQ_LOGIN.SQL.Clear;
//Count of BLOGINs
DM.AQ_LOGIN.SQL.Add('select count(BLOGIN) from BENU where BLOGIN = ''' + Login + ''' AND BPW = ''' + Passwort + '''');
DM.AQ_LOGIN.Open;
//LoginReply.Action tells the client then what to do with the LoginReply.Value
LoginReply.Action := 0;
//if user unique
if DM.AQ_LOGIN.Fields[0].AsInteger = 1 then
begin
//LoginReply.Value = 1 means the client is allowed to log in
LoginReply.Value := 1;
//THIS RETURNS THE WSA 10057 EXCEPTION of user is unique
Server_Form.ServerSocket.Socket.SendBuf(LoginReply, SizeOf(LoginReply));
end
else
begin
//LoginReply.Value = 0 means the client is NOT allowed to log in
LoginReply.Value := 0;
//THIS RETURNS THE WSA 10057 EXCEPTION if user is NOT unique
Server_Form.ServerSocket.Socket.SendBuf(LoginReply, SizeOf(LoginReply));
end;
//Close ADOQuery
DM.AQ_LOGIN.Close;
//Close DB Connection
DBConnect(false);
end;
end;
//Is called when something is in the socket connection
procedure TServer_Form.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var Query: TQuery;
begin
//Reads from the Socket (cant use ServerSocket.Socket.ReceiveBuf whysoever, but this is another thread)
Socket.ReceiveBuf(Query, SizeOf(Query));
case Query.Action of
//If Query.Action = 0, which means the client tries to login call UserCheckExist
0: UserCheckExist(Query.Login, Query.Passwort);
//Otherwise, getfuckedup
else ShowMessage('Query Action not defined');
end;
end;
奇妙なことに、クライアントからログイン+pwを2回送信する必要があります。
初めて送信(クライアント)すると、サーバーでonClientConnectとonAcceptを取得します。2回目に(クライアント)を送信すると、サーバーは、マークした行までコードを実行します。10057WSA例外が発生します。
なぜこのエラーが発生するのですか?ただし、奇妙なことに、「ソケットが開いていません」という例外が発生する行の直前でサーバーのソケットを開くと、とにかく取得します。