PDA

Visualizza la versione completa : [C/C++]: Chat client/server in C


pishta
27-07-2006, 01:57
Salve a tutti sto cercando di implementare una semplice chat in c. In pratica l'idea di partenza è quella di un server che sta in accept() e accetta connessioni. ogni utente che si collega ottiene la lista dei partecipanti alla chat. la parte difficile che non riesco a pensare è quella del client: stavo pensado che quando il client, attraverso un processo figlio comunica con un'altro client deve poter continuare ad accettare connessioni...ma per far questo dovrei implementare un piccolo server nel client??è qui che c'è un pò di panico...

Qualcuno può aiutarmi, anche con un'idea ad alto livello?

grazie ciao ciao

zero85
27-07-2006, 02:40
Allora io fare i così: (te lo scrivo in pseudocodice dato che non so se ti serve per win o unix)

strurrurerei il server in questo modo:



socket list_sock;
socket client_sock[MAX_CONN];
int c=0;
int main()
{
/*Inizializzo le strutture del socket, setto porta e
tipi di connessioni accettate*/
list_sock.bind(); //binding del socket
crea_thread(list, argomenti);
aspetta_thread(list);
exit 0;
}

void *list(void *dummy)
{
while(1)
{
client_sock[c] = list_sock.accetta_nuova();
c++;
crea_thread(dispatch_message,c)
}
}

void *dispatch_message(void *dummy)
{
int s = dummy;
while(client_sock[s].read(buffer)) //rimane in attesa di dati dal client, se la connessione viene chiusa la funzione ritorna 0 ed esce dal ciclo
{
/*rispedisce il messaggio a tutti i client
*/
}
esci_thread(0);
}


e fin qui tutto dovrebbe essere abbastanza normale.

veniamo al client


socket sock;
int main()
{
/*Inizializzo la struttura socket e stabilisco la connessione
*/
sock.connect();
crea_thread(read_mess,NULL)
crea_thread(send_mess,NULL)
aspetta_thread(list);
aspetta_thread(list);
exit 0;
}

void *read_mess()
{
while(sock.read(buffer))//leggo fino alla terminazione della connessione
{
print(buffer); //stampo a video
}
}

void *send_mess()
{
while(1)
{
scan(buffer); //leggo da tastiera
socket.send(buffer)//invio il messaggio al server;
}
exit_thread(0);
}


In pratica il client crea 2 thread separati: 1 rimane in attessa che l'utente scriva qualcosa o che lanci un comando (magari uno /exit per terminare o /list per avere la lista dei client connessi), mentre l'altro thread rimane in ascolto e si occupa di ricevere e stampare a video i messaggi provenienti dal server (tutte le comunicazioni tra client passano prima dal server)

pishta
28-07-2006, 19:06
grazie. Scusa ma questa chat però fa parlare uno con tutti. io intendevo un comportamento di chat simile a quello di skype o msn in cui ognuno ha la sua lista utenti e può separatamente chattare con ognuno dei suoi contatti

norbix
19-08-2006, 18:02
tattaratttatà, mi sono iscritto qui solo per questo topic praticamente!

allora, ti serve un server, i client si connettono a questo grande server che può fare 2 cose: dare le informazioni per contattare l'utente desiderato oppure fare da centralino (chiama lui l'utente desiderato e poi vi lascia parlare assieme)

eh già così fanno i server MSN, infatti se usate netstat potete vedere che quando contattate qualcuno l'IP destinatario è quello di un server MSN, che registrerà felicemente le vostre conversazioni.......

comunque io ti ho dato la soluzione, e adesso tu mi passi una semplice chat in riga di comando per windows eh ok?

appena me la passi se vuoi proviamo assieme a fare questa nuova chat con tutta la lista utenti.... aspetto una tua risposta, e mi faccio un giro sul meravigliuoso forum!

scancode
19-08-2006, 19:14
mi inserisco anch'io.

ho implementato, e scelto per fare un multiplayer, il metodo asincrono usando WSAAsyncSelect ((SOCKET)gSocketListen, hWnd, SERVER_EVENT, (FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE ));

Il server e il client sono strutturati senza usare thread anche perchè il metodo asincrono permette di comunicare appunto in modo non-bloccante sulle sock.

Rispondendo a pishta:

La struttura è avere un server che smista i messaggi a tutti i client. Ogni client invia un messaggio e il server smista il messaggio a tutti volendo meno a chi a spedito il messaggio.
se cerchi su google WSAAsyncSelect FD_READ winsock troverai molte cose a riguardo.

Invece per norbix e zero85

In pratica è una chat che funziona sia in modalità chat ovvero il client invia il proprio nome e id al server e il server smista a tutti i clients il messaggio meno a chi l'ha spedito.
Oppure posso usare, checcando "modo continuo", che i clients in modo automatico inviano il proprio nome e id in modo continuo al server il quale smista a tutti i messaggi arrivati.

Tutto funziona alla grande in particolar modo in modalità chat ovvero modo non continuo cliccando appunto sul pulsante "Invia messaggio".

Il problema riscontrato è il "modo continuo" dove appunto si comporta come un multiplayer per game dove i clients inviano i propri dati, in questo caso, nome e id reinviati dal server a tutti.

La domanda per chi volesse rispondere:

A me interessa il modo multiplayer "invio dati in modo continuo" proprio per sviluppare un multiplayer ma con il winsock sotto win.

Ho creato dopo 3 anni di lavoro con directplay un multiplayer dove directplay ho riscontrato che è molto ma molto performante questo strato di DP è fatto molto bene e scritto con funzioni a basso livello davvero ben fatto secondo me.

In pratica questo motore posso usarlo in qualunque game.
L'ho testato con amici sul web, integrando il multiplayer nel motore grafico del game, e devo dire che si gioca che è una meraviglia. Le prestazioni migliori si hanno giocando con modem a 56k dove ho riscontrato un tempo di latenza di ping + basso a differenza delle linee veloci come l'adsl.

Parlando con un amico tempo fà mi disse che non era daccordo in quanto directplay non è + sviluppata da microsoft in pratica nei prossimi sistemi non sarà + integrata quindi in futuro il programmatore dovrà sviluppare o con il winsock che è uno strato di comunicazione di default o altri metodi integrati per le nuove tecnologie di comunicazione.

Ebbene io non sono daccordo in quanto secondo me è si che microsoft non aggiornerà + directplay ma saranno sempre integrate sui sistemi come per esempio è successo a directinput dove sono sempre integrate ma ferme alla versione 8.1 e non per questo non + utilizzate.

Finita questa considerazione torniamo al problema:

Ora i 2 aspetti del multiplayer confronto tra Directplay e il winsock che ho fatto:

Con directplay i clients inviano al server il messaggio stampato nella listbox i dati in arrivo sul server sono perfetti anche aumentando i clients l'aspetto della listbox è il seguente:

//dati in arrivo al server directplay e smistamento del messaggio a tutti i clients
okay 0
ciao 1
amico 2
okay 0
ciao 1
amico 2
okay 0
ciao 1
amico 2

Ora provando il modo continuo con il winsock che ho fatto i dati in arrivo sul server winsock è il seguente:
//dati in arrivo al server winsock e smistamento del messaggio a tutti i clients
okay 0
okay 0
okay 0
okay 0
amico 2
okay 0
okay 0
okay 0
okay 0
okay 0
ciao 1
ciao 1
ciao 1

ecc ecc.

come si può notare con il winsock strutturato nel modo che ho fatto asincrono come detto sopra i dati in arrivo al server non sono fluidi ed omogenei come con directplay i tempi di latenza di ping sono molto + alti.

Spero di aver chiarito il problema riscontrato.

Ho creato anche un server sempre con il winsock che lavora con CRITICAL_SECTION e thread e il risultato è analogo al test sopra con il winsock mentre con Directplay la fluidità e la velocità dei dati è imbarazzante.

cosa ne pensate come fare per rendere fluido il passaggio dei dati con il winsock??

norbix
19-08-2006, 19:57
amico, sinceramente ci ho capito ben poco!

XD io comunque pensavo (quando avrò sta char in riga di comando sottomano) di fare un server che gestisce le connessioni, ovvero un client si connette e gli invia il nome utente, il server poi gli invia al client la lista degli utenti che si sono connessi in totale, e magari tramite una piccola verifica dice se sono o no online, la cosa è semplicissima secondo me, almeno in riga di comando, dove basta inviare le scritte e il server con degli IF decide cosa fare, esempio:

client si connette al server e invia > nome_utente = janni <
sul server ci sarà una cosa del tipo: if ( -testo ricevuto- == nome_utente) allora invia un OK al client e anche la lista di tutti gli utenti, online e non..... riguardo al consumo di banda è minimo, qualche KB ogni tanto.....

if ( -testo ricevuto- == nome_utente) intendo se la prima cosa che dice è il nome utente da l'OK altrimenti invia un testo con scritto "inserisci il nome utente prima!", capite? a me piace il programma in console, grafico no, quindi se mi date una chat semplice in console possiamo metterci e in un giorno la finiamo sta chat!

ma non capisco cosa intendi "con questo multiplayer"!

scancode
19-08-2006, 20:13
non hai mai sentito la parola multiplayer??

il multiplayer è lo giocare in "rete" con il pc contro altri pc... tutto quà!

Per giocare online con un game un pc deve comunicare agli altri clients i propri dati che sono per esempio il proprio nome l'id la sua posizione nel gioco ecc ecc.

Per questo, come detto, ho sviluppato un multiplayer con directplay e ora sto migrando con il winsock per i problemi spiegati sopra, ma anche per fare un'altra cosa in programmazione.

In sostanza ho sviluppato con winsock inTCP il mio multiplayer o chat la differenza tra chat e multiplayer è che con la chat il messaggio è spedito cliccando sul pusante "invia messaggio" mentre il multiplayer il messaggio viene spedito non cliccando su un pulsante ma in ciclo di render() tipo:

void render()
{

send messaggio //dati spediti di continuo che possono essere
...nome id posizioneGiocatore altridati ecc ecc

}

Sopra ho spiegato che usando il winsock in modo asincrono i dati come si vede dalla pseudo tabella non sono fluidi e omogenei come con Directplay

norbix
19-08-2006, 22:01
sisi so cos'è il multiplayer, non sapevo se intendevi proprio quello per i giochi!

ma sto directplay cosa sarebbe :bhò:

scancode
19-08-2006, 22:27
Originariamente inviato da norbix
sisi so cos'è il multiplayer, non sapevo se intendevi proprio quello per i giochi!

ma sto directplay cosa sarebbe :bhò:


DirectX (in origine chiamato "Game SDK") è una collezione di API per lo sviluppo semplificato di videogiochi per Windows. Il kit di sviluppo (SDK) è disponibile gratuitamente sul sito della Microsoft. Le DirectX venivano distribuite dai produttori di giochi stessi insieme al videogioco, ma sono ora incluse direttamente in Windows. La 9.0c è la versione attuale delle librerie.

Da molti le DirectX sono considerate come il miglior set di api grafiche mai creato. Le DirectX vengono utilizzate da molte industrie per creare famosi videogiochi.

alka
19-08-2006, 23:29
Originariamente inviato da norbix
tattaratttatà, mi sono iscritto qui solo per questo topic praticamente!

Attenzione, in generale, a non rispondere a discussioni troppo vecchie o da tempo inattive.


Originariamente inviato da norbix
comunque io ti ho dato la soluzione, e adesso tu mi passi una semplice chat in riga di comando per windows eh ok?

Ogni discussione segue un proprio filone: se devi porre una domanda che esula da quella corrente, ricordati di aprire una nuova discussione.

Al momento, nessun problema specifico: è solo una raccomandazione per il futuro che cerco di fornire ai nuovi utenti. :)

Ciao! :ciauz:

Loading