|
| Multithreaded TServerSocket? Fra : Thomas Eg Jørgensen |
Dato : 08-03-01 21:28 |
|
Hejsa, jeg forsøger at lave en ny thread til hver socket som laves når der
kommer en ny forbindelse, jeg har:
<----------code---------------->
function SocketHandleThread(socket: Pointer):longint;
begin
showmessage(socket.LocalAddress);
while true do begin
sleep(2000);
end;
end;
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket:
CustomWinSocket);
var
ThreadId:cardinal;
begin
CreateThread(nil, 0, @SocketHandleThread, socket, 0, ThreadId);
end;
<----------code---------------->
men uanset hvad jeg gør så får jeg altid en access violation error et sted i
sourcen til socket-komponenten. Min ide er at det går alt for mig når jeg
forsøger at smide min socket med over i min nye thread som parameter, tror
den enten ikke kommer over som den skal eller også henter jeg den ikke
rigtigt, dunno, håber i kan hjælpe?
På forhånd tak
MVH
Thomas
| |
Stig Johansen (09-03-2001)
| Kommentar Fra : Stig Johansen |
Dato : 09-03-01 05:26 |
|
Hej.
"Thomas Eg Jørgensen" <thomas@kontorbutikken.dk> wrote in message
news:988pv0$k7d$1@news.inet.tele.dk...
> Hejsa, jeg forsøger at lave en ny thread til hver socket som laves når der
> kommer en ny forbindelse, jeg har:
>
[klip]
Stop stop, brug de indbyggede funktioner i TServerSocket.
Først skal du have en serversocket på eks. en form.
Sæt den til blocking mode.
Den event, du skal have fat i er OnGetThread ( og evt. OnThreadEnd).
Under denne event, kreerer du din egen tråd, eksempel:
SocketThread := TLogonThread.Create(TRUE,ClientSocket);
Her er der tale om min egen klasse, der er nedarvet fra klassen
TServerClientThread
Og HUSK, aldrig bruge 'VCL - desktopfunktioner' fra en Thread.
--
Med venlig hilsen/Best Regards
Stig Johansen - stig@w3data.dk
W3 Data - mailto@w3data.dk
| |
Thomas Eg Jørgensen (09-03-2001)
| Kommentar Fra : Thomas Eg Jørgensen |
Dato : 09-03-01 09:44 |
|
"Stig Johansen" <stig@w3data.dk> wrote in message
news:iXYp6.1109$lk1.29575@twister.sunsite.dk...
> Hej.
>
> Den event, du skal have fat i er OnGetThread ( og evt. OnThreadEnd).
> Under denne event, kreerer du din egen tråd, eksempel:
> SocketThread := TLogonThread.Create(TRUE,ClientSocket);
Men hvordan(hvor) håndtere du så indkommende/udgående data?
TServerClientThread har da ingen events som jeg kan bruge til dette?
MVH
Thomas
| |
Stig Johansen (10-03-2001)
| Kommentar Fra : Stig Johansen |
Dato : 10-03-01 06:07 |
|
Hej.
"Thomas Eg Jørgensen" <thomas@kontorbutikken.dk> wrote in message
news:98a52a$cp6$1@news.inet.tele.dk...
>
> "Stig Johansen" <stig@w3data.dk> wrote in message
> news:iXYp6.1109$lk1.29575@twister.sunsite.dk...
> > Hej.
> >
> > Den event, du skal have fat i er OnGetThread ( og evt. OnThreadEnd).
> > Under denne event, kreerer du din egen tråd, eksempel:
> > SocketThread := TLogonThread.Create(TRUE,ClientSocket);
>
> Men hvordan(hvor) håndtere du så indkommende/udgående data?
> TServerClientThread har da ingen events som jeg kan bruge til dette?
>
Når man er ude i Multithreaded programmering, skal du bruge blocking
sockets.
Her bliver der ikke sendt en message som under non blocking sockets.
Her er lidt klip fra noget dem jeg lavede for nogle år siden. Stumpen
modtager en fil, der sendes fra en klient.
--
Med venlig hilsen/Best Regards
Stig Johansen - stig@w3data.dk
W3 Data - mailto@w3data.dk
------ declaration
TServerThread = class(TServerClientThread)
private
fSocketStream : TWinSocketStream ;
fFileStream : TFileStream ;
protected
procedure ClientExecute; Override;
public
PROPERTY SocketStream : TWinSocketStream READ fSocketStream WRITE
fSocketStream ;
PROPERTY FileStream : TFileStream READ fFileStream WRITE
fFileStream ;
end ;
-----------
kodestumper
-------------
procedure TForm1.ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
VAR
SocketStream : TWinSocketStream ;
FileStream : TFileStream ;
begin
Addevent('Get thread');
SocketStream := TWinSocketStream.create( ClientSocket, 10000 );
FileStream := TFileStream.Create('DELETE.ME',fmCreate OR
fmShareExclusive );
SocketThread := TServerThread.Create(TRUE,ClientSocket);
(SocketThread AS TServerThread).SocketStream := SocketStream ;
(SocketThread AS TServerThread).FileStream := FileStream ;
SocketThread.FreeOnTerminate := TRUE ;
SocketThread.Resume ;
end;
procedure TForm1.ServerSocketThreadEnd(Sender: TObject;
Thread: TServerClientThread);
begin
Addevent('Thread end');
end;
//--------------------------------------------------------------------
FUNCTION DoReadStream ( Stream : TWinSocketStream ; Buffer : Pointer ; Count
: INTEGER ) : BOOLEAN ;
VAR
P : Pchar ;
Total : INTEGER ;
Delta : INTEGER ;
TimeOut : INTEGER ;
BEGIN
IF Count = 0 THEN BEGIN
Result := TRUE ;
EXIT ;
END ;
TimeOut := 0 ;
Result := TRUE ;
Total := 0 ;
P := Buffer ;
WHILE Total < Count DO BEGIN
TRY
Delta := Stream.Read(P^,Count-Total);
EXCEPT
EXIT ;
END ;
IF Delta = 0 THEN BEGIN
INC(Timeout);
WHILE NOT Stream.WaitForData(1000) AND ( TimeOut < 20 ) DO
INC(TimeOut);
IF Timeout >= 20 THEN BEGIN
Result := FALSE ;
EXIT ;
END ;
END ELSE
TimeOut := 0 ;
INC(P,Delta);
INC(Total,Delta);
END ;
END ;
//--------------------------------------------------------------------
PROCEDURE TServerThread.ClientExecute;
VAR
FileLength : INTEGER ;
MemoryStream : TMemoryStream ;
Buffer : ARRAY[1..cMaxBuffer] OF BYTE ;
ReceivedSize : INTEGER ;
ThisSize : INTEGER ;
OkToContinue : BOOLEAN ;
BEGIN
// Read filesize
ReceivedSize := 0 ;
OkToContinue := TRUE ;
IF DoReadStream ( SocketStream,Addr(FileLength),SIZEOF(FileLength)) THEN
BEGIN
WHILE ( ReceivedSize < FileLength ) AND OkToContinue DO BEGIN
ThisSize := FileLength - ReceivedSize ;
IF ThisSize > cMaxBuffer THEN
ThisSize := cMaxBuffer ;
OkToContinue := DoReadStream ( SocketStream,@Buffer,ThisSize);
IF OkToContinue THEN
fFileStream.Write(Buffer,ThisSize);
Inc(ReceivedSize,ThisSize);
// ELSE SOME ERROR HANDLING
END ;
END ;
IF Assigned(fSocketStream) THEN
fSocketStream.Free ;
IF Assigned(fFileStream) THEN
fFileStream.Free ;
Terminate ;
END ;
| |
xx@xx.xx (21-05-2001)
| Kommentar Fra : xx@xx.xx |
Dato : 21-05-01 14:18 |
|
In article <jEiq6.2989$lk1.87342@twister.sunsite.dk>, "Stig Johansen" <stig@w3data.dk> wrote:
>Hej.
>
>
>"Thomas Eg Jørgensen" <thomas@kontorbutikken.dk> wrote in message
>news:98a52a$cp6$1@news.inet.tele.dk...
>>
>> "Stig Johansen" <stig@w3data.dk> wrote in message
>> news:iXYp6.1109$lk1.29575@twister.sunsite.dk...
>> > Hej.
>> >
>> > Den event, du skal have fat i er OnGetThread ( og evt. OnThreadEnd).
>> > Under denne event, kreerer du din egen tråd, eksempel:
>> > SocketThread := TLogonThread.Create(TRUE,ClientSocket);
>>
>> Men hvordan(hvor) håndtere du så indkommende/udgående data?
>> TServerClientThread har da ingen events som jeg kan bruge til dette?
>>
>
>Når man er ude i Multithreaded programmering, skal du bruge blocking
>sockets.
>Her bliver der ikke sendt en message som under non blocking sockets.
>
>Her er lidt klip fra noget dem jeg lavede for nogle år siden. Stumpen
>modtager en fil, der sendes fra en klient.
>
Hvorfor skal det være blocking
jeg har lavet en winsock komponent der indeholder en
server der starter en tråd når der kommer et request og så laver et event
programmet kan reagere på
men korrekt det er ikke smart at lave VCL kald i eventet
mvh
Torben Bovtrup
| |
|
|