Citat:
OK. A kako se sve to resava kada je u pitanju program sa FLTK (ili nekim drugim,
nebitno) GUI-jem.
Nisam se javljao do sada, jer svo moje (sa)znanje vezano za socket-e je vezano
isključivo za VCL/C++Builder i komponente TClientSocket i TServerSocket (da ne
pominjem Indy ovog puta) koje su poprilično dobro koncipirane za problematiku
socket-a. Inače do sada sam projektovao/razvio desetak servera (servisna
aplikacija+socket-i) i to su za sada moje najkorisnije aplikacije, iako imam puno
složenijih projekata.
Dakle, sve ovo što kažem viđenje je iz ugla C++Builder-a i klasa TClientSocket i
TServerSocket.
Citat:
Programiranje sa prozorima je, koliko shvatam, event based. Znaci, delovi programa
se izvrsavaju kad se dogodi neki event.
Tačno, i to se odnosi i na socket-e.
Citat:
U network programiranju ja moram da imam neku petlju koja non stop proverava
da li je nesto stiglo na socket.
Ne. Kod ovih klasa čeka se event OnRead() i kod servera i kod klijenta, ili
OnGetThread() što je ono što mislim da bi tebe zanimalo! Drugim recima
sve je event based dok ne dodje do citanja, a onda mora thread i to samo u "modu"
za "uporedno" čitanje. Ima i neki drugi mod!
Citat:
Da li onda da razdvajam socket klasu u nezavisnu nit, ili da to resim na neki
drugi nacin.
Da, ali ako koristiš gore pomenute klase, novi thread ćeš otvarati samo radi
čitanja u "modu" koji predviđa uporedno čitanje.
Citat:
Vezbe radi je to sada chat klijent [...]
Koliko ja znam chat je i klijent i server, je li tako? Barem u najprostijem obliku,
kada su sve IP adrese poznate (stalne).
Evo ovako:
KLIJENT:
TClientSocket ima dva radna režima: ctBlocking i ctNonBlocking. Kod ovog prvog, kada
otvaras vezu sa serverom, recimo ClientSocket1->Open(), dok se ne pronadje server
ceo program je "blokiran". Ceknaje na server zavisi od nekih unapred u sistemu podesenih
mera, tako da cekanje u LAN-u traje 5 sekundi, dok cekanje na Internet-u traje mnogo
duze, mislim 30 sekundi. Kako program razlikuje LAN od Interneta, pojma nemam...
U ovom modu nema teorije da nekako prekines (limitiras) vreme cekanja sa event baziranim
nacinima, npr TTimer komponentom ciji bi event trebao da se "okine" na podeseno vreme,
recimo ClintSocket1->Close(). Jedini nacin je nekim zasebnim thread-om za prekidanje.
Ali tako se retko kada radi. Mnogo cesce se u smislu klijenata koristi onaj drugi,
ctNonBlocking mode, gde jednostavno pokusas otvaranje, a program "trci" dalje,
pa ako dodje do neke greske, javlja se event OnError(). Takodje try/catch je
*obavezan* jer program moze da se zbuni.
Evo kako se tada otvara konekcija:
Code:
// SOCKET_WAIT_FOR_CONNECTION je broj milisekundi kada odustajes od potrage...
try
{
// **********************************************************************
SmsClientSocket->Active = false;
SmsClientSocket->Address = CONFIG_SMS_IP;
SmsClientSocket->Port = CONFIG_SMS_PORT;
// **********************************************************************
SmsClientSocket->Active = true;
// **********************************************************************
int ms_start = GetTickCount();
while ( GetTickCount() - ms_start < SOCKET_WAIT_FOR_CONNECTION )
{
Forms::Application->ProcessMessages();
if ( SmsClientSocket->Active )
break;
}
if ( !SmsClientSocket->Active )
{
SmsClientSocket->Active = false; // <-- IZGLEDA TOTALNO GLUPAVO ALI NIJE!
LogMessage( "sursrv.exe : SendToRecipients() > Sms > Timeout" );
GoSendMessageToLog ( SERVICE_SMS_SENDING_SOCKET_TIMEOUT_ERROR );
}
else
{
bool R = GoSendData ( SmsClientSocket, SmsMemStream, SOCKET_BUFFER_PORTION );
int ms_start = GetTickCount();
while ( GetTickCount() - ms_start < SOCKET_PROCESSMESSAGES )
Forms::Application->ProcessMessages();
if ( !R )
{
LogMessage( "sursrv.exe : SendToRecipients() > Sms > GoSendData()" );
GoSendMessageToLog ( SERVICE_SMS_SENDING_SOCKET_ERROR );
SystemOk = false;
// ...
}
else
{
// ...
}
}
// **********************************************************************
}
catch ( const Exception &e )
{
LogMessage( "sursrv.exe : SendToRecipients() > Sms > Exception" );
GoSendMessageToLog ( SERVICE_SMS_SENDING_SOCKET_ERROR );
//SystemOk = false;
}
Ovo je otprilike kako resavam konektovanje + slanje: GoSendData(). Ova poslednja
funkcija je moja (nije clanica neke klase).
E sad, sledi drugi deo price:
SERVERI:
Serveri takodje mogu da imaju dva radna rezima: stNonBlocking i stThreadBlocking.
Server ne polazi ni od kakve pretpostavke i kakvom je rezimu bio klijent i
obrnuto. Da ne duzim, logicno je da server uporedo obradjuje vise zahteva i tada
se koristi event mod stThreadBlocking i OnGetThread() event. U njemu otvaras
thread, gde vrsis citanje i eventualno "odgovaranje" klijentu.
Ako te ovo i dalje zanima (kod i ostalo), javi pa da nastavim...