Newsgroup: it.comp.os.linux.development
Titolo: Lib Socket[LONG]

Per crearmi un layerino per le mie app ho scritto i seguenti file:
/**
* A Sock Server Func
*/
#ifndef SERVER_H
#define SERVER_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
/* Numero di Port sul quale il server acccetta la connessione */
#define PORT 4000
#define LOG
/** Crea */
int CreaServerSocket(int nwait)
{
	int il_socket, errore;
	struct sockaddr_in temp;
 
	il_socket = socket(AF_INET,SOCK_STREAM,0);
	temp.sin_family = AF_INET;
	temp.sin_addr.s_addr = INADDR_ANY;
	temp.sin_port = htons(PORT);
 
	errore = fcntl(il_socket,F_SETFL,O_NONBLOCK);
 
	errore = bind(il_socket,(struct sockaddr*) &temp,sizeof(temp));
	errore = listen(il_socket,nwait);
 
	return il_socket;
}
/** Spedisce */
void ServerRiceviMessaggio (int sock, char *buf)
{
	printf("%s\n", Messaggio);
	if (recv(sock, Messaggio, strlen(buf), MSG_OOB ) <0)
	{
		if(LOG) fprintf(stdout, "Impossibile comunicare col client\n");
		ChiudiSocket(sock);
		exit(1);
	}
	if(LOG) fprintf(stdout, "Messaggio inviato!\n");
	return;
}
/** Chiude */
void ChiudiServerSocket(int sock)
{
	close(sock);
	return;
}
#endif
/**
* A Sock Client Func
*/
#ifndef CLIENT_H
#define CLIENT_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
/* Numero di Port sul quale il client richiede la connessione */
#define PORT 4000
#define LOG
/** Chiude */
void ChiudiSocket(int sock)
{
	close (sock);
	return;
}
/** Crea */
int CreaSocket(char* Destinazione)
{
	struct sockaddr_in temp;
	struct hostent *h;
	int il_socket;
	int errore;
 
	temp.sin_family=AF_INET;
	temp.sin_port=htons(PORT);
	h = gethostbyname(Destinazione);
	if (h==0)
	{
		if(LOG) fprintf(stdout, "Connessione IP alfanumerico... fallito!\n");
		exit(1);
	}
	bcopy(h->h_addr,&temp.sin_addr,h->h_length);
	il_socket = socket(AF_INET,SOCK_STREAM,0);
	errore = connect(il_socket,(struct sockaddr*) &temp, sizeof(temp));
	return il_socket;
}
/** Spedisce */
void SpedisciMessaggio (int sock, char* Messaggio)
{
	printf("%s\n", Messaggio);
	if (send(sock, Messaggio, strlen(Messaggio), MSG_OOB ) <0)
	{
		if(LOG) fprintf(stdout, "Impossibile comunicare col server\n");
		ChiudiSocket(sock);
		exit(1);
	}
	if(LOG) fprintf(stdout, "Messaggio inviato!\n");
	return;
}
#endif
Vanno bene o sbaglio qualcosa???
Tnk 100000000
-- 
Kleidemos
Un computer a un altro quando si incontrano:
"Ciao, come ti boota oggi???"

 Tnk 100000000
Ho esaminato in 2 minuti il tuo codice, spero di esaminarlo meglio
piu' tardi. Anche iO, con lo Stevens alla mano mi sono
scritto delle funzioni con lo stesso scopo (le ho a casa).
Alcuni suggerimenti che gia' mi sento di darti:
La funzione server e' bene che setti l' opzione REUSEADDR, altrimenti se
ammazzi il server, lo stato di time_wait non te lo fa riavviare (come
porta occupata) per un minuto.
la var errore e' sempre settata, ma mai controllata. Inutile fare test
all' interno della funzione. anziche' una var locale, usa un parametro
passato per riferimento, cosi' la gest. degli errori la fai da progr.
Altrimenti puoi codificare le condizioni di errore ritornando diversi
valori negativi (-1 rr socket() -2 err. fcntl() ecc) perche' in posix
e' garantito che un numero di descrittore valido ristituito da socket()
e' positivo. quindi in caso di err ritorni valori negativi,
altrimenti il socket.
non ho capito quel
#define LOG
e
if(LOG) ...
credo dovesse essere
#ifdef LOG
...
le funzioni trasmetti e ricevi andrebbero concepite a mio dire in modo
piu' sofisticato:
tu setti lato server il socket non bloccante (il che e' strano, ma non so'
a cosa ti servono) quindi accept non sara' bloccante. forse chiamerai 
accept() solo dopo test con select(). ora, qualsiasi IO non sara' bloccante
a preschindere che i dati vengano scritti un tutto, in parte o per niente.
quindi dovresti scrivere la funz. trasmetti per iterare la trasmissione con
il puntatore all buffer incrementato del numero di char trasmessi che
ritorna
send(), ed essendo il socket non bloccante potrebbe essere anche 0 e il
loop potrebbe essere infinito.
per la ricevi vale la stessa regola speculare.
riassumendo:
socket stream
scritture su socket bloccante sono bloccanti se non si
puo' scrivere niente, (esempio finestra TCP non confermata dal ricevitore)
ma si sblpccano scrivendo anche solo una parte del messaggio.
su socket non bloccanti ritorna comunque o un errore da trattare o il
numero
di caratteri scritto.
Letture su sochet bloccanti sono bloccanti fino a che non ci sono caratteri
da leggere, su socket non bloccanti ritorna comunque o err. da gestire o
numro char letti.
di solito l' IO su socket NON BLOCCANTI viene prima testato con select()
un concetto fondamentale: per socket stream NON ESISTONO MESSAGGI ma
appunto
stream, cioe' chi trasmette puo fare 10 send e chi riceve puo' fare 5 read
o
viceversa. per questo trasmetti() e ricevi() devono essere concepite 
opportunamente.
ciao
Roberto
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Se nn ti disturba potrei vedere magari via mail le tue funzioni cosi da 
vedere le differenze :=)
Ciao e tnk


 #define CLIENT_H
questo #ifndef #endif va nei file h non c... e. Se queto č un fileh
non dovresti scrivere dentro codice, ma solo prototipi (al - io l'ho
intesa cos', se sbaglio correggimi)


http://taurus.polito.it/~lioy/01fqt/src.zip
qui ci sono piccoli programmi con i socket (fatti dal mio prof)