Oppure

Loading
23/05/09 17:34
ShadowsA7X
sono un novellino con il c++ :blush:
vorrei chiedervi se mi potete postare un programma in c++ di una chat client windows e
un server linux che possano comunicare a vicenda con queste condizioni:
Parte server (Linux)
•    Il codice del server in linguaggio C deve accettare un massimo di 10 connessioni
•    Per ciascuna connessione viene creato un processo figlio che gestisce la connessione
•    Si preveda una struttura dati in memoria condivisa per inoltrare i messaggi ricevuti dal server ai diversi client
•    Ciascun messaggio conterrà all’inizio il NICKNAME dell’utente che ha scritto il messaggio
•    Si preveda la gestione della TERMINAZIONE della comunicazione con un client alla ricezione del messaggio “0FINE”, il server deve togliere dalla lista delle connessioni il client disconnesso
•    Il server, una volta attivato rimane sempre in ascolto, NON si preveda la possibilità di fermarlo

Parte client (Windows)
•    Il client si connette al server fornendo un NIKNAME (non si preveda il controllo se il NICKNAME è già usato da un'altra persona)
•    riceve i messaggi e li visualizza a video
•    richiede un nuovo messaggio da inviare al server
•    l’accesso alla risorsa condivisa “schermo” viene gestita mediante semaforo binario (mutex)
•    gestione dello scroll video quando i messaggi via via ricevuti superano la dimensione (di righe) dello schermo



anche se mi sembra molto sfacciato vi mando due prototipi: uno della client e l'altro del server



Vi prego aiutatemi !! :hail:

Server linux:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>

#include <sys/select.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
fd_set pri; // lista descrittori per istruzione select()
fd_set set_lettura; // lista temporanea descrittori
int sdgr; // numero descrittore piu' alto

struct in_addr vet[10]; // memorizza IP client connessi

FD_ZERO(&pri); // azzera lista descrittori
FD_ZERO(&set_lettura);
    
int SPORT = 3600;    // Porta TCP Server
int server, client;
    
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
    
int client_len = sizeof(client_addr);
int byte;
    
char buffer[20]; // buffer messaggi, da modificare
    
    
    //    Struttura con le informazioni sul server per effettuare il BIND
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons((u_short) SPORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    server = socket (AF_INET, SOCK_STREAM, 0);
//server = socket (PF_INET, SOCK_STREAM, 0);
    if (server < 0)
    {
        perror ("Errore nella socket";);
return(-1);
    }
int val = 1;
if (setsockopt(server,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(int))<0)
{
perror ("Errore nella setsockopt";);
return(-1);
}
    //    Il BIND associa al socket una porta
    if (bind (server,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)
{
perror ("Errore nella bind";);
return(-1);
}

    if (listen(server,10) < 0) // 10 = numero richieste simultanee...
{
perror ("Errore nella listen";);
return(-1);

}
    //    L'applicazione rimane in attesa di connessione
    printf("Server in attesa di connessione\n";);

FD_SET(server,&pri); // aggiunge 'server' alla lista dei descrittori
sdgr = server; // conserva il descrittore piu' grande
    for (;;) // ciclo infinito
    {
     set_lettura=pri; // set di appoggio per non modificare lista 'pri'
if (select(sdgr+1,&set_lettura,NULL,NULL,NULL) < 0) // imposta ricerca descrittore
{
perror ("Errore nella select";);
return(-1);
}
int i;
for (i = 0; i <=sdgr; i++) // ciclo ispezione delle connessioni per cercare dati in arrivo
{
if(FD_ISSET(i,&set_lettura)) // trovato socket con dati
{
printf("ricerca: socket trovato %d\n",i);
if (i == server)
{
     printf("accept\n";);        
     if((client = accept (server,(struct sockaddr*) &client_addr, &client_len))<0)
perror("server: errore nella accept";);
else
{
printf("sock client creato %d\n",client);

FD_SET(client,&pri); // aggiunge il socket al set pri
if (client > sdgr)
sdgr = client; // aggiorna descrittore piu' grande
printf("server : connessione da %d su socket %d\n",inet_ntoa(client_addr.sin_addr),client);
vet[client]=client_addr.sin_addr; // salva IP del client
}
}
else
{
// gestione dei dati in arrivo da un client
printf("controllo dati su descrittore %d\n",i);
        if ((byte = recv(i,buffer,20,0)) <=0)
{
if (byte == 0)
printf("Connessione chiusa sul socket %d \n",i);
else
perror("Errore in ricezione";);
close(i);
FD_CLR(i,&pri); // toglie il socket dalla lista        
}
else // invio dei dati ricevuti ai vari client
{
int j;

for(j = 0; j < sdgr; j++)
{

if (FD_ISSET(j,&pri))
//if (FD_ISSET(j,&set_lettura))
{
if (j!=server && j!=i)
{
printf("trasmetto dati su socket %d \n",j);
send(j,buffer,20,0);
//send(j,"prova",20,0);
}
}
}
}

}
} // fine IF (FD_ISSET
     } // fine for ispezione connessioni
} // fine ciclo infinito
} // fine main

Client windows

#include <iostream>
#include "uSocket.h" //uso una libreria contenente il socket client
using namespace std;

SOCKET client;
volatile HANDLE hMutex; // Global hMutex Object
int xT=1;
int yT=1;

int xM = 1;
int yM = 20;
char schermo [25][80];

void init_schermo(char s[][80])
{
    for (int i=0; i < 25; i++)
        strcpy(s[i]," ";); // modificare
}
void stampa(char s[][80])
{
for (int i=0; i < 20; i++)
        cout << s[i] << endl;
cout << "Client :";
}
void inserisci(char s[][80],char r[])
{
    for (int i = 0; i < 20; i++) // da modificare con gestione scroll video
    {    
        if (s[i][0]==' ')
        {
            strcpy(s[i],r);
     break;
        }
    }
}
void getcursor (int &x, int &y)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
x=csbi.dwCursorPosition.X;
y=csbi.dwCursorPosition.Y;
}

void setcursorposition(int x, int y)
{
HANDLE hConsoleOutput;
COORD dwCursorPosition;
cout.flush();
dwCursorPosition.X = x;
dwCursorPosition.Y = y;
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition);
}

void ThreadFiglio()
{
char Risposta[80];
for(;;)
{
ricevi(client,Risposta);
    WaitForSingleObject(hMutex,INFINITE); //####
    inserisci(schermo,Risposta);
    setcursorposition(1,1);
    stampa(schermo);
    ReleaseMutex(hMutex); //####
}
ExitThread(0);
}

int main(void)
{
     char Messaggio[80];
        hMutex=CreateMutex(NULL,FALSE,NULL); // mutex object
client = connessione_client("192.168.5.57",3600);

        HANDLE hThread;
DWORD hid;

hThread = CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)ThreadFiglio,NULL,NORMAL_PRIORITY_CLASS, &hid);

        init_schermo(schermo);

        do
        {
WaitForSingleObject(hMutex,INFINITE); //####
setcursorposition(xM,yM);
         cout <<"Client : ";
         setcursorposition(xM+9,yM);
         ReleaseMutex(hMutex); //####
         cin.getline(Messaggio,80);
        
invia(client,Messaggio);
        }
        while (strstr(Messaggio,"fine";)==NULL);
closesocket(client);
        return 0;
}




Ultima modifica effettuata da ShadowsA7X 23/05/09 17:51
aaa
23/05/09 20:13
lorenzo
1) se sei un novellino dovresti cominciare con qualcosa di semplice
2) oltre ai due programmi vuoi qualcosa d'altro? ma per chi ci hai preso? per la microsoft?
3) quando si mette del codice si usa il tag code
4) se mi sai spiegare il codice dei due "prototipi" allora ti farò tutte le scuse del caso ma se, come penso, non lo sai fare, significa che hai copiato del codice che ti hanno dato/hai preso da internet

ps: non sono un indovino ma questo mi sembra un programma per un esame universitario
aaa
23/05/09 20:55
ShadowsA7X
Purtroppo ti so dire poche cose su questo programma,
poichè il mio professore, diciamo che ha tanta fretta di farci imparare tutti i comandi e io anche molti dei miei compagni non ha capito niente! infatti il codice ce l'ha dato così su due piedi e pretendeva che facessimo tutto da soli...
quindi ero qui a cercare in giro alcuni spunti su come fare questo programma(o anche qualcuno sapesse aiutarmi)
scusate il modo in cui ho messo il codice poichè sono anche uno che non usa i forum, ed è tutto nuovo per me :blush:
nei 2 programmi usiamo un bel po' di comandi che riguardano l'uso dei semafori(i comandi mutex e releasemutex) e i thread per i 10 utenti rendendo possibile la connesione ai client .i programmi funzionano si, ma si devono aggiungere le varianti elencate prima.
Visto che sono nuovo qua chiedo scusa di nuovo per la sfacciataggine...
P.S. io sono in 4° informatica!! visto che consideri i programmi come da universitari dovresti capirmi per la difficoltà...
P.P.S diciamo che sono novellino per il fatto che ero in un'altra scuola d'informatica e il c++ non l'avevo mai visto prima, io usavo il c#!
:(
aaa
28/05/09 12:01
giulian79
Postato originariamente da ShadowsA7X:

Purtroppo ti so dire poche cose su questo programma,
poichè il mio professore, diciamo che ha tanta fretta di farci imparare tutti i comandi e io anche molti dei miei compagni non ha capito niente! infatti il codice ce l'ha dato così su due piedi e pretendeva che facessimo tutto da soli...
quindi ero qui a cercare in giro alcuni spunti su come fare questo programma(o anche qualcuno sapesse aiutarmi)
scusate il modo in cui ho messo il codice poichè sono anche uno che non usa i forum, ed è tutto nuovo per me :blush:
nei 2 programmi usiamo un bel po' di comandi che riguardano l'uso dei semafori(i comandi mutex e releasemutex) e i thread per i 10 utenti rendendo possibile la connesione ai client .i programmi funzionano si, ma si devono aggiungere le varianti elencate prima.
Visto che sono nuovo qua chiedo scusa di nuovo per la sfacciataggine...
P.S. io sono in 4° informatica!! visto che consideri i programmi come da universitari dovresti capirmi per la difficoltà...
P.P.S diciamo che sono novellino per il fatto che ero in un'altra scuola d'informatica e il c++ non l'avevo mai visto prima, io usavo il c#!
:(

ciao,anche io fevo fare piu' o meno lo stesso progetto,se vuoi possiamo aiutarci a vicenda
aaa