ginter87
01-03-2010, 09:12
Intanto mi scuso perché ho postato un thread senza titolo. Conosco le regole del forum più o meno e non so perché ho scritto in quel modo o.o mah
perciò, sto scrivendo un programma in C non perché ho tempo libero ma perché ho un'esame giorno 8 e purtroppo devo.
Praticamente ho vn server che invia delle domande ad un client anzi, a più client così ho messo una send dentro un ciclo for del tipo
for(k=0; k<3;k++)
{
for(i=0; i<2; i ++)
{
if(send(cilent_sd[i], domande[k], strlen(domande),0 )>0)
{ // fa tutta una serie di cose
adesso, la prima la manda ai due client. La seconda, la terza no. Mi ritorna quell'errore scritto nel titolo del post. Perché? Ho esame l'8. Aiutatemi!!
tomminno
01-03-2010, 11:06
for(k=0; k<3;k++)
{
for(i=0; i<2; i ++)
{
if(send(cilent_sd[i], domande[k], strlen(domande),0 )>0)
{ // fa tutta una serie di cose
adesso, la prima la manda ai due client. La seconda, la terza no. Mi ritorna quell'errore scritto nel titolo del post. Perché? Ho esame l'8. Aiutatemi!!
Manca un bel pò di codice:
come hai inizializzato l'array cilent_sd?
E stai dicendo che domande[k] è lungo quanto l'array domande invece che la lunghezza dell'elemento.
bobbytre
01-03-2010, 11:19
Intanto mi scuso perché ho postato un thread senza titolo. Conosco le regole del forum più o meno e non so perché ho scritto in quel modo o.o mah
perciò, sto scrivendo un programma in C non perché ho tempo libero ma perché ho un'esame giorno 8 e purtroppo devo.
Praticamente ho vn server che invia delle domande ad un client anzi, a più client così ho messo una send dentro un ciclo for del tipo
for(k=0; k<3;k++)
{
for(i=0; i<2; i ++)
{
if(send(cilent_sd[i], domande[k], strlen(domande),0 )>0)
{ // fa tutta una serie di cose
adesso, la prima la manda ai due client. La seconda, la terza no. Mi ritorna quell'errore scritto nel titolo del post. Perché? Ho esame l'8. Aiutatemi!!
dovresti postare il codice se vuoi avere maggiori possibilità di risolvere il problema.
domande cos'e' ? un char ** ?
sei sicuro quindi che strlen(domande) nella send è corretto ?
ginter87
01-03-2010, 17:50
ECCo il codice
CODICE SERVER
#include <stdio.h> // per I/O
#include <stdlib.h> // per exit, malloc, atoi...
#include <unistd.h> // per exec, getpid...
#include <pthread.h> // thread
#include <semaphore.h> //semafori posix
#include <sys/types.h> // standard posix
#include <netinet/in.h> //
#include <sys/socket.h> // socket
#include <signal.h> // segnali
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <semaphore.h>
#include <sys/types.h>
#include <semaphore.h>
#include <fcntl.h>
#define totpost 3 //numero studenti
#define MAX 3 //numero domande
#define LEN 1024 //caratteri per riga: 1023+0 del messaggio
#define PORT 16000 //porta dove il server accetta le connessioni
#define semaforo "sem_mutex"
#define MACS 2
char domande[MAX][LEN]; //tabella caricata con domande e risposte
char risposte[MAX][2]; //tabella caricata con le risposte corrette
void *caricamento(void *arg); //funzione svolta dal thread1
char risp[2];
sem_t *mutex;
int sd, i, j, k;
int punteggi[MAX][MACS], punteggio;
int tab[totpost][2];
struct sockaddr_in server_addr; // struttura dati di configurazione
struct sockaddr_in client_addr;
socklen_t client_len;
int main(int argc, char *argv[])
{
system("clear"); //system chiama il comando UNIX "clear"
printf("Server avviato con pid = %d\n", getpid());
int i;
//THREAD
int res, pid;
pthread_t thread1; //primo thread per il caricamento
void *thread_result;
res=pthread_create(&thread1, NULL, caricamento,NULL);
if (res!=0)
{ perror("\n****ERRORE CREAZIONE THREAD***\n");
exit(1);
}
res=pthread_join(thread1, &thread_result); //come la wait
printf("thread1 terminato con stato: %d\n", (int*)thread_result);
//FINE THREAD
//inizializzo il vettore punteggi
for(j=0;j<2;j++)
for(i=0;i<totpost;i++)
{
punteggi[i][j]=0;
punteggi[i][j]=0;
}
//fine
//VISUALIZZAZIONE DOMANDE PER CONFERMA CARICAMENTO
printf("\n\n******ELENCO DOMANDE******\n");
for(k=0;k<MAX;k++)
printf("Domanda numero %d:\t%s\nRisposta Corretta:\t%s\n\n",k+1,domande[k],risposte[k]);
//SOCKET
int client_sd[totpost];
// preparazione dei dati relativi al bind
server_addr.sin_family = AF_INET; //dominio
server_addr.sin_port = htons(PORT); //host to network
server_addr.sin_addr.s_addr = INADDR_ANY; //associa al server l'indirizzo della macchina
client_len = sizeof(struct sockaddr_in);
//SOCKET
int sd=socket(AF_INET, SOCK_STREAM, 0);//restituisce l'identificativo del socket
if(sd<0)
{
perror("creazione socket errata!!\n");
exit(-1);
}
//BIND
printf("Effettuo la bind del socket con la porta ds\n", PORT);
if (bind(sd, (const struct sockaddr *) &server_addr, client_len) < 0)
{
perror("Durante il bind\n");
exit(1);
}
//LISTEN
printf("Mi metto in attesa di connessioni sulla porta %d\n", PORT);
if (listen(sd, 2) < 0)
{
perror("Durante il listen");
exit(1);
}
printf("Entro nel ciclo for in cui accetto connessioni\n");
// itero il tutto cn un ciclo for ke crea un sd dedicato per ogni client accettato
for(i=0;i<totpost;i++)
{
//ACCEPT: accetta le commessioni che gli arrivano
client_sd[i] = accept(sd, (struct sockaddr *) &client_addr, &client_len);
if (client_sd[i] < 0)
{
perror("Durante l'accept\n");
exit(1);
}
//FORK: creazione figli
pid = fork();
if (pid == 0) //FIGLIO
{
printf("sono il servente: %d\n",getpid()); //figlio ke s collega con il client
printf("Connessione con client accettata sul socket %d\n", client_sd[i]);
break;
}
if(pid < 0) //ERRORE
{
printf("\n\n ERRORE FORK\n\n");
exit(1);
}
if(pid >0) //PADRE
{
sleep(2); //ASPETTA LA TERMINAZIONE DEI FIGLI ... MANCU PER METTERE NA WAIT
}
//CARICAMENTO TABELLE CON IDENTIFICATIVI ... pero' ci son pobbbbbemi
tab[i][0]=pid;
tab[i][1]=client_sd[i];
}
// crea/preleva un semaforo con valore iniziale a 1 (per noi un mutex)
mutex = sem_open(semaforo, O_CREAT, 0777, 1);
if (mutex == 0)
{
perror("sem_open");
exit(1);
}
else
{
for(k=0;k<MAX;k++) //conta le domande da inviare
{
printf(" \nInvio la %d domanda ... ", k+1);
for(i=0;i<totpost;i++)
{
if(send(client_sd[i],domande[k],strlen(domande[k]),0)>0)
{
printf(" \n*********** DOMANDA %d inviata ************ ", k+1);
printf("\nAttendo una risposta dagli studenti per circa 10 secondi\n");
sleep(10);
//ricevo la prima risposta quindi semaforo rosso per tutti gli altri
printf("\n");
printf("Attendo l'acquisizione del mutex\n");
if (sem_wait(mutex) < 0)
{
perror("Su sem_wait");
exit(1);
}
printf("Mutex acquisito correttamente\n");
printf("Effettuo tutte le operazioni\n");
res=recv(client_sd[i], risp, 2, 0);
if(res>0)
{
printf("\nRisposta ricevuta: \t %s\n",risp);
sleep(3);
printf("\n Effettuo il controllo di correttezza sulla risposta\n\n");
if(strcmp(risposte[k],risp)==0)
{
printf("\nLa risposta corretta è stata data dallo studente con ID %d\n",client_sd[i]);
punteggi[i][j]=client_sd[i];
punteggi[i][j+1]++;
}
}
sleep(1);
printf("Rilascio il mutex e dormo 1 secondo\n");
if (sem_post(mutex) < 0)
{
perror("Su sem_post");
exit(1);
}
}
}
}
}
for(i=0;i<totpost;i++)
printf("\nEcco i vari punteggi:\n\nID Studente: %d\t Punteggio: %d\n",client_sd[i],punteggi[i][j+1]);
close(sd);
printf("\n");
printf("\n\t\t ********************* ");
printf("\n\t\t * * ");
printf("\n\t\t * TERMINATO!!!!! * ");
printf("\n\t\t * * ");
printf("\n\t\t ********************* ");
printf("\n\n");
system("killall -q server");
} //FINE MAIN
/*THREAD CONTROLLO MAX E MIN PUNTEGGI
void *punteggi(void *args)
{
int i, j, temp;
for (i = (array_size - 1); i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
if (numbers[j-1] > numbers[j])
{
temp = numbers[j-1];
numbers[j-1] = numbers[j];
numbers[j] = temp;
}
}
} da modificare ma è l'algoritmo bubble sort per ordinare in modo crescente o decrescente il vettore punteggio per decretare il "vincitore"
}*/
//THREAD CARICAMENTO DOMANDE
void *caricamento(void *args)
{
char s[1024];
char r[2];
int k;
int risp;
printf("\n\n******** CARICAMENTO DOMANDE START ******** ");
for(k=0; k<MAX; k++)
{
printf("\nInserisci la %d domanda e le 4 risposte\t \n", k+1);
gets(s);
if(strlen(s)==0)
{
printf("\nERRORE: STRINGA VUOTA!! REINSERIRE DATI NELLA DOMANDA");
k--;
}
else if(strlen(s)>LEN)
{
printf("\nERRORE: STRINGA GRANDE!! REINSERIRE DATI NELLA DOMANDA");
k--;
}
else
strcpy(domande[k], s);
printf("\nInserisci la %d risposta corretta\n", k+1);
gets(r);
if(strlen(r)==0)
{
printf("\nERRORE: STRINGA VUOTA NELLA RISPOSTA !! REINSERIRE DATI.");
k--;
}
else if(strlen(r)>1)
{
printf("\nERRORE: troppi caratteri, inserire una sola lettera nella risposta");
k--;
}
else
strcpy(risposte[k], r);
}
sleep(3);
pthread_exit(EXIT_SUCCESS);
}
//FINE THREAD CARICAMENTO DOMANDE
CODICE CLIENT
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#define LEN 1024
#define PORT 16000
#define MAX 3
int sd, res, ress, i, j;
char risp[2], punt[2];
struct sockaddr_in server_addr;
struct hostent *hostinfo;
socklen_t len;
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Utilizzo: ./%s <indirizzo>\nHai dimenticato di inserire l'indirizzo!!! \n", argv[0]);
exit(1);
}
system("clear");
//SOCKET
printf("Creo il socket\n");
sd = socket(PF_INET, SOCK_STREAM, 0);
if (sd < 0)
{
perror("Durante la creazione del socket\n");
exit(1);
}
// prepara i dati per la connessione con il server
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
hostinfo = gethostbyname(argv[1]);
if (hostinfo == NULL)
{
printf("Non è stato possibile risolvere il nome del server\n");
exit(1);
}
else
server_addr.sin_addr = *((struct in_addr *) hostinfo->h_addr);
//CONNECT
printf("Apro la connessione\n");
if (connect(sd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)) < 0)
{
perror("Durante la connect");
exit(1);
}
//semaforo verde
printf(" ***************Ricevo la prima domanda e la visualizzo a schermo****************");
char buffer[MAX][LEN];
for(i=0;i<=MAX;i++)
{
res=recv(sd, buffer[i], LEN+1,0);
if(res>0)
{
printf("\nLa domanda a cui devi rispondere è: %s \n Inserisci il carattere corrispondente alla tua risposta\n", buffer[i]);
gets(risp);
sleep(3);
res=send(sd, risp, strlen(risp), 0);
if (res>0)
printf("\n La Risposta Inviata Correttamente è: \t %s\n",risp);
}
}
exit(0);
}
COMUNQUE grazie per avermi risposto. Mi dai speranza. Ho scritto male quel "domande" perchè dovrebbe essere un vettore di stringhe come vedrai dal codice.
Grazie ancora.
PS Se ci sono errori dimmi un pò come posso risolverli. L'esame si avvicina e son disperatissima :cry:
ginter87
01-03-2010, 17:51
Manca un bel pò di codice:
come hai inizializzato l'array cilent_sd?
E stai dicendo che domande[k] è lungo quanto l'array domande invece che la lunghezza dell'elemento.
---- oddio, non ho inizializzato l'array client_sd ... ma devo inizializzarlo quindi? AAAAAAAAA :muro:
ginter87
01-03-2010, 18:13
---- oddio, non ho inizializzato l'array client_sd ... ma devo inizializzarlo quindi? AAAAAAAAA :muro:
ho provato e adesso mi da errore
Socket operation on non-socket
O_O
tomminno
01-03-2010, 19:49
Scusa ma usare un debugger no?
Fai il fork poi il processo figlio esegue il break, uscendo dal ciclo di accept e tralasciando la valorizzazione di tab.
Il codice prosegue e successivamente esegui for(i=0;i<totpost;i++) ma non tutti i client_sd sono stati valorizzati o per lo meno non vedo niente che sia in attesa della completa valorizzazione di client_sd.
ginter87
01-03-2010, 21:19
Scusa ma usare un debugger no?
Fai il fork poi il processo figlio esegue il break, uscendo dal ciclo di accept e tralasciando la valorizzazione di tab.
Il codice prosegue e successivamente esegui for(i=0;i<totpost;i++) ma non tutti i client_sd sono stati valorizzati o per lo meno non vedo niente che sia in attesa della completa valorizzazione di client_sd.
e secondo te, scusa la mia ignoranza, come posso procederE? cioè che correggo? cosa aggiungo? hai ragione ... non mi convinceva quel pezzo ma non so come fare ... :muro: :cry:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.