Newsgroup: it.comp.programmare.win32
Titolo: CSocket e Multithreading

Sto tentando di creare un'applicazione Client - Server utilizzando la classe
CSocket che mi permetta di serializzare oggetti tramite CArchive.
Non riesco a capire perchč subito dopo il metodo Create() del socket viene
creato un altro thread. Nelle documentazioni MFC non ho trovato nulla a
riguardo. Ne sapete qualcosa?
 
Il mio problema č se gestire o no l'applicazione con il multithreading oppure
no. Il mio dubbio a riguardo č che ci potrebbero essere rallentamenti nella
rete che bloccano l'applicazione se non utilizzassi il multithreading.
Che ne pensate?
 
Ciao a tutti
 
-- 
Caronte
-- 
Inviato da 
Newsgate.Localinfo.IT
 Web Service
http://newsgate.localinfo.it

 Che ne pensate?
Aldilà di tutto, se usi Visual Studio 6 con MFC 4.2 i sockets in
multithreading non li puoi utilizzare a causa di un problema di MFC (non
so se il problema è stato corretto in versioni successive di MFC); io
stesso tempo fa ho provato a realizzare un'applicazione server tcp/ip e
chiaramente la volevo fare in multithreading affinché potesse gestire più
connessioni contemporaneamente, ma non c'è stato verso di far funzionare
ne' CSocket ne' CAsyncSocket in un thread diverso dal primario, le ho
provate tutte, e alla fine ho dovuto riscrivermi i sockets a mano.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 multithreading non li puoi utilizzare a causa di un problema di MFC 
Probabilmente si trova qualche classe CxxxSocket abilitata al 
multithreading su siti come CodeProject...

 provate tutte, e alla fine ho dovuto riscrivermi i sockets a mano.
 
Ho già trovato il modo di far funzionare la classe CSocket in un thread
diverso dal primo, almeno nella teoria, ma non l'ho ancora testato
praticamente. Basta fare Detach del Socket e riattaccarlo (Attach) nel secondo
thread.
 
Ad ogni modo non ho risolto il mio dubbio.
Posso gestire più connessioni contemporanee con un solo thread attraverso la
classe CSocket, Windows genererà una coda di richieste sul socket che andrò a
processare una per volta. Poco importa nel mio caso, le transazioni riguardano
pochi Kbyte.
La cosa che invece mi preoccupa di più è il fatto che durante il Receive,
specialmente sul lato server ho l'applicazione bloccata fin quando non finisce
di ricevere i dati. E' vero che i dati sono pochi, ma se ci sono problemi di
rete durante la trasmissione? Il socket è TCP!
 
Per questo avevo intenzione di far girare l'intera classe derivata da CSocket
su un altro thread. Prima di farlo però volevo capire perchè la classe
CSocket, già di suo, genera un secondo thread!!!
Non è che il lavoro che vorrei fare già viene fatto in CSocket? Quel thread
infame che cosa fa?
 
Ciao


 infame che cosa fa?
Sai che non lo so? O.o forse allora è proprio questo il motivo percui MFC
non permette di gestire manualmente sockets da threads diversi...
Ciao



 
Forse sono riuscito a risolvere tutti i problemi.
Utilizzando AfxBeginThread(RUNTIME_CLASS(...)) e inviando un messaggio con
PostThreadMessage al thread per avviare il socket (parlo del socket in
listening (server)). Pare che in questo modo tutte le possibili
inizializzazioni, messaggi e altre diavolerie che utilizza CSocket risiedano
sul thread secondario.
 
Adesso lo provo, scrivendo le classi come si deve. Se ti interessa poi ti
faccio sapere.


 faccio sapere.
Si, mi interesserebbe molto, grazie! :-)


 Si, mi interesserebbe molto, grazie! :-)
 
prego! Dimmi se per te è una soluzione ragionevole e funzionale.


 prego! Dimmi se per te è una soluzione ragionevole e funzionale.
Capisco; quindi tu in pratica mi dici che se creo un thread derivando una
classe da CWinThread (piuttosto che passando direttamente una ThreadProc)
il thread creato non ha problemi nella gestione della mappa dei sockets;
hmmm, lo terrò presente per la prossima volta che dovrò fare un programma
Tcp/Ip con MFC. :)
Però mi sorge un dubbio: dal momento che il socket creato da Accept è
stato creato nel thread A, come fai ad esser sicuro del fatto che esso di
fatto lavori nel thread B? Come fa cioè, Windows a capire che le notifiche
tu le vuoi ricevere nel thread B piuttosto che nel thread A? Magari fai
tutto il lavorone e poi scopri che l'evento OnReceive viene processato dal
thread sbagliato... secondo me non è sufficiente il "reattachment"
(chiamiamolo così) dell'handle del socket; IMHO devi richiamare
AsyncSelect dal nuovo thread dopo aver fatto il reattachment; casomai fai
una prova: quando gestisci l'evento OnReceive, fai un TRACE che ti stampa
l'ID del thread corrente ottenuto da GetCurrentThread, poi fammi sapere.
Ciao.


 Ciao.
 
Il thread che viene generato da OnAccept(), detach(), attach() e compagnia
bella lavora sul thread B. Te lo do per certo anche perchč il thread A (quello
che riceve OnAccept() esegue Accept(TMPSock) su un socket temporaneo che alla
fine della funzione OnAccept esce dal suo ambito e quindi cancellato dalla
memoria.
OnReceive viene sicuramente gestita dal thread B visto che il socket non č piů
quello in listening ma quello generato su OnAccept().
 
Ad ogni modo io ho gestito anche il Thread A, come tu l'hai chiamato, cioč
quello che gestisce il socket in Listening (il server) su un thread separato
dal primario che quindi non interferisce minimamente con l'applicazione.
 
Nel peggiore dei casi: cioč si blocca tutto il sistema dei socket :) ho
comunque il controllo dell'applicazione perchč tutto gira su thread separati.
 
La chiave di tutto questo č far eseguire le chiamate Attach() del client e
Create() del server in ascolto nel thread interessato. Questo l'ho ottenuto
inviando dei messaggi al thread e non chiamando direttamente le funzioni.


 inviando dei messaggi al thread e non chiamando direttamente le funzioni.
Ma il punto č che quando termini un thread, tutti gli handles che esso ha
creato vengono distrutti (anche quelli dei sockets), quindi se tu hai un
certo thread con un socket in ascolto, e questo thread nel gestire
OnAccept crea un nuovo socket utilizzando Accept, in teoria uscendo dal
thread il socket creato con Accept non si dobvrebbe distruggere???
E comunque il punto fondamentale che a me interessa sapere č il seguente:
ho sperimentato di persona che se uso AfxBeginThread per creare un worker
thread (cioč senza creare una classe apposta, ma semplicemente passando la
ThreadProc) il thread creato non č in grado di gestire *nessuna* chiamata
CAsyncSocket::Xxx, perché non inizializza le mappe relative; domanda: se
invece creo un thread con l'altro sistema, cioč derivando una classe da
CWinThread e chiamando l'altra versione di AfxBeginThread, il thread
creato č in grado di gestire CAsyncSocket e compagne? E se sě, tutto
questo in Visual Studio 6.0 con MFC 4.2?
Ti ringrazio per le risposte :)
