23/05/09 17:34
ShadowsA7X
sono un novellino con il c++
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 !!
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;
}
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 !!
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