|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Oct 2007
Messaggi: 938
|
[C] Problema con le socket
Ciao a tutti, avrei un problemuccio:
uso code::blocks 8.02 per compilare i miei script in C..ultimamente ho deciso di mettermi alla prova con la programmazione di socket..cosa per cui sono necessarie delle librerie, appunto le winsock. volevo sapere come "aggiungerle" in modo tale da poter far funzionare i miei algoritmi. Questi sono i codici del client e del server (semplice algoritmo riguardante la "comunicazione" tra cliente e cameriere di una pizzeria) Codice:
#include <windows.h>
#include <fcntl.h>
#include <stdio.h> // Libreria STANDARD INPUT/OUTPUT //
#include <winsock.h> // Libreria per la gestione delle socket sotto Windows //
#include <string.h> // Libreria per la gestione delle stringhe //
void crea_socket ();
void invia_pizze (SOCKET remoteSocket, int ordinazione);
void invia_bibite (SOCKET remoteSocket, int ordinazione, double prezzo_pizza_scelta);
int main()
{
crea_socket();
return 0;
}
void crea_socket ()
/* Questa function crea le socket di ascolto e ricezione e gestisce la scelta effettuata dall'utente nel menù principale
del client */
{
SOCKET listenSocket; // Creazione della socket di ascolto. //
SOCKET remoteSocket; // Creazione della socket di ricezione. //
SOCKADDR_IN Server_addr;
SOCKADDR_IN Client_addr;
// Per assegnare una porta ed un indirizzo IP alle socket si creano queste variabili strutturate //
int sin_size, scelta_effettuata, ordinazione;
/* La variabile "ordinazione" viene usata come un flag. Se è impostata su zero, significa che l'utente non ha deciso di
effettuare un'ordinazione, altrimenti assume il valore uno. */
short port; // La porta da utilizzare per la comunicazione con il server. //
int wsastartup; // Variabile di controllo per il successo della WSAStartup //
int ls_result, prezzo_pizza_scelta; // "ls_result" = variabile di controllo per il successo della listen //
WORD wVersionRequested = MAKEWORD(2,2);
/* Il parametro MAKEWORD(2,2) della WSAStartup ricerca nel sistema la versione 2.2 della Winsock e setta la versione che
gli viene passata come quella più alta che il chiamante può usare. */
WSADATA wsaData;
wsastartup = WSAStartup(wVersionRequested, &wsaData);
/* Inizializzazione della libreria Socket.
wVersionRequested (param. di input) = indica la versione più alta delle socket di Windows che il chiamante può usare.
WSAData (param. di output) = un puntatore alla struct WSADATA, che deve ricevere i dettagli sulle socket di Windows. */
if (wsastartup != NO_ERROR)
printf("Errore WSAStartup()\n");
// Rilevamento dell'eventuale errore all'avvio della libreria per la gestione delle socket. //
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/* Creazione della Socket che si porrà in ascolto di richieste del Client
AF_INET = utilizzo della classe IP4
SOCK_STREAM = socket di tipo full-duplex. Si possono leggere e scrivere flussi di byte contemporaneamente e
indipendentemente nel canale. I dati non vengono mai perduti o ricevuti in modo duplicato.
IPPROTO_TCP = utilizzo del protocollo TCP/IP */
if (listenSocket < 0)
printf("Server: errore nella creazione della socket.\n");
else
printf("La Listening Socket e' partita\n");
// Rilevamento dell'eventuale errore nella creazione della socket //
port = 4000;
/* La struttura SOCKADDR_IN (Server_addr) specifica l'indirizzo famiglia, l'indirizzo ip e la porta del server con cui
connettersi */
Server_addr.sin_family = AF_INET; // Utilizzo della classe IP4 //
Server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
// La funzione "inet_addr" converte una stringa contenente un indirizzo IP4 nel formato adatto per la struct SOCKADDR_IN //
Server_addr.sin_port = htons(port);
// La funzione "htons" prende un numero a 16 bit e lo converte in un numero a 16 bit nel formato IP4. //
/* La seguente porzione di codice effettua la bind sull’indirizzo e porta ora specificati. La bind richiede il descrittore di
socket,indirizzo da assegnare alla socket,lunghezza in byte di Server_addr */
if (bind(listenSocket,(SOCKADDR*)&Server_addr,sizeof(struct sockaddr_in)) < 0)
printf("Server: errore durante la bind.\n"); //Rilevamento dell'eventuale errore durante la bind //
ls_result = listen(listenSocket, SOMAXCONN);
/* La socket si pone in "ascolto" tramite la listen(). La listen richiede il descrittore socket, la massima lunghezza della
coda di connessioni entranti */
if (ls_result < 0)
printf("Server: errore durante la listen.\n"); // La listen non è riuscita //
else
printf("La Socket e' in Ascolto\n"); // La socket accetta la richiesta di connessione del Client //
sin_size = sizeof(struct sockaddr_in);
ordinazione = 0;
remoteSocket = accept(listenSocket, (struct sockaddr *)&Client_addr,&sin_size);
/* La funzione accept indica la socket su cui il server ha accettato la connessione, l’indirizzo del client che ha effettuato
la richiesta di connessione che è stata accettata e la lunghezza di questo indirizzo. */
printf("Accettata Connessione con Client: %s\n",inet_ntoa(Client_addr.sin_addr));
// Il Server accetta il messaggio dal Client //
recv(remoteSocket, (char *)&scelta_effettuata, sizeof(int), 0);
/* Ricezione dal client dell'opzione selezionata dall'utente, memorizzata all'interno della variabile "scelta_effettuata".
Nella recv vengono indicati la socket utilizzata, la variabile in cui viene salvato il messaggio e la sua dimensione in byte.
Eseguo un cast per trattare "scelta_effettuata" come una stringa, parametro standard della recv. */
printf("Messaggio Arrivato: %d \n", scelta_effettuata);
prezzo_pizza_scelta = 0;
if (scelta_effettuata == 1) // Il cliente vuole vedere il menù delle pizze //
invia_pizze (remoteSocket, ordinazione);
if (scelta_effettuata == 2) // Il cliente vuole vedere il menù delle bibite //
invia_bibite (remoteSocket, ordinazione, prezzo_pizza_scelta);
if (scelta_effettuata == 3) /* L'utente ha deciso di effettuare un'ordinazione. La variabile "ordinazione" viene
impostata su uno. */
{
ordinazione = 1;
invia_pizze (remoteSocket, ordinazione);
}
}
void invia_pizze (SOCKET remoteSocket, int ordinazione)
/* Questa funzione invia al client il menù delle pizze e, nel caso in cui la variabile "ordinazione" sia impostata su uno,
gestisce l'ordinazione delle stesse */
{
int i,pizza_scelta;
double prezzo_pizza_scelta;
char pizze [6][50] = {"01. Margherita \t\t\t3,10 Euro\n", "02. Olio e pomodoro \t\t2,80 Euro\n", "03. Ripieno \t\t\t4,20 Euro\n",
"04. Quattro stagioni \t\t4,50 Euro\n", "05. Capricciosa \t\t4,50 Euro\n", "06. Filetto di pomodoro \t4,20 Euro\n"};
double prezzi_pizze [] = {3.10,2.80,4.20,4.50,4.50,4.20};
printf ("Sto inviando:\n");
for (i=0; i<6; i++)
{
send(remoteSocket,pizze[i], strlen(pizze[i]),0);
/* Al passo i-simo, invio al client l'i-sima stringa. Nella send vengono indicati la socket da utilizzare, la fonte del
messaggio e la sua dimensione.*/
printf ("%s", pizze[i]); // Stampo a video la stringa che sto inviando //
}
if (ordinazione == 0) /* L'utente vuole solo visualizzare il menù delle pizze */
{
printf("Chiudo il Server\n");
close(remoteSocket); // Chiudo la socket utilizzata //
WSACleanup(); // Questa istruzione termina l'utilizzo della libreria per la gestione delle socket. //
crea_socket ();
}
if (ordinazione == 1) // L'utente vuole ordinare //
{
printf ("Aspetto il codice pizza.\n");
recv (remoteSocket, (char *)&pizza_scelta, sizeof(int), 0);
/* Ricezione dal client della pizza scelta dall'utente, memorizzata all'interno della variabile "pizza_scelta". Nella recv
vengono indicati la socket utilizzata, la variabile in cui viene salvato il messaggio e la sua dimensione in byte. Eseguo
un cast per trattare "pizza_scelta" come una stringa, parametro standard della recv. */
printf ("Ho ricevuto il cod pizza %d\n", pizza_scelta);
printf ("Sto inviando:\n");
send(remoteSocket,pizze[pizza_scelta-1], strlen(pizze[pizza_scelta-1]),0);
/* Invio al client la pizza selezionata dall'utente, il cui codice è contenuto in "pizza_scelta". Nella send vengono
indicati la socket da utilizzare, la fonte del messaggio e la sua dimensione. Lo spiazzamento dell'indice è necessario in
quanto lo shape di un array di size n nel linguaggio C è di tipo (0, n-1) */
printf ("%s", pizze[pizza_scelta-1]); // Stampo a video la stringa che sto inviando //
prezzo_pizza_scelta= prezzi_pizze[pizza_scelta-1]; // Salvo il prezzo della pizza nella variabile "prezzo_pizza_scelta" //
invia_bibite (remoteSocket, ordinazione, prezzo_pizza_scelta);
// Chiamo la function "invia_bibite", passando la socket attualmente in uso //
}
}
void invia_bibite (SOCKET remoteSocket, int ordinazione, double prezzo_pizza_scelta)
/* Questa funzione invia al client il menù delle bibite e, nel caso in cui la variabile "ordinazione" sia impostata su uno,
gestisce l'ordinazione delle stesse */
{
int i, bibita_scelta;
char bibite [4][50] = {"01. Coca cola \t\t\t1,00 Euro\n", "02. Birra \t\t\t1,50 Euro\n", "03. Aranciata \t\t\t1,00 Euro\n",
"04. Minerale \t\t\t0,50 Euro\n"};
double prezzi_bibite [] = {1.00,1.50,1.00,0.50};
double prezzo_bibita_scelta;
printf ("Sto inviando:\n");
for (i=0; i<4; i++)
{
send(remoteSocket, bibite[i], strlen(bibite[i]),0);
/* Al passo i-simo, invio al client l'i-sima stringa. Nella send vengono indicati la socket da utilizzare, la fonte
del messaggio e la sua dimensione.*/
printf ("%s", bibite[i]); // Stampo a video la stringa che sto inviando //
}
if (ordinazione == 0)
{
printf("Chiudo il Server\n"); // L'utente vuole solo visualizzare il menù delle pizze //
close(remoteSocket);
WSACleanup(); // Questa istruzione termina l'utilizzo della libreria per la gestione delle socket. //
crea_socket ();
}
if (ordinazione == 1) // L'utente vuole ordinare //
{
printf ("Aspetto il codice bibita.\n");
recv (remoteSocket, (char *)&bibita_scelta, sizeof(int), 0);
/* Ricezione dal client della bibita scelta dall'utente, memorizzata all'interno della variabile "bibita_scelta".
Nella recv vengono indicati la socket utilizzata, la variabile in cui viene salvato il messaggio e la sua dimensione
in byte. Eseguo un cast per trattare "bibita_scelta" come una stringa, parametro standard della recv. */
printf ("Ho ricevuto il cod bibita %d\n", bibita_scelta);
printf ("Sto inviando:\n");
send(remoteSocket,bibite[bibita_scelta-1], strlen(bibite[bibita_scelta-1]),0);
/* Invio al client la bibita selezionata dall'utente, il cui codice è contenuto in "bibita_scelta". Nella send vengono
indicati la socket da utilizzare, la fonte del messaggio e la sua dimensione. Lo spiazzamento dell'indice è necessario
in quanto lo shape di un array di size n nel linguaggio C è di tipo (0, n-1) */
printf ("%s", bibite[bibita_scelta-1]); // Stampo a video la stringa che sto inviando //
prezzo_bibita_scelta = prezzi_bibite[bibita_scelta-1] + prezzo_pizza_scelta; // Calcolo il totale //
send(remoteSocket,(char *)&prezzo_bibita_scelta, sizeof(double),0);
/* Invio al client il totale dell'ordinazione effettuata dall'utente, memorizzato all'interno della variabile
"prezzo_bibita_scelta". Nella send vengono indicati la socket da utilizzare, la fonte del messaggio e la sua
dimensione in byte. Eseguo un cast per trattare "prezzo_bibita_scelta" come una stringa, parametro standard della send. */
printf ("Invio al client la somma di %.2f e %.2f che fa %.2f\n", prezzi_bibite[bibita_scelta-1],prezzo_pizza_scelta, prezzo_bibita_scelta);
// Stampo a video il totale che invio al client //
printf("Chiudo il Server\n");
close(remoteSocket);
WSACleanup(); // Questa istruzione termina l'utilizzo della libreria per la gestione delle socket. //
crea_socket ();
}
}
Codice:
#include <windows.h>
#include <fcntl.h>
#include <stdio.h> // Libreria STANDARD INPUT/OUTPUT //
#include <winsock.h> // Libreria per la gestione delle socket sotto Windows //
#include <string.h> // Libreria per la gestione delle stringhe //
void stampa_inizio ();
void scelta ();
void menu_pizze (int scelta, int ordinazione);
void menu_bibite (int scelta);
void ordine (SOCKET clientsocket);
void menu_bibite_ordinazione (SOCKET clientsocket);
int main()
{
stampa_inizio ();
return 0;
}
void stampa_inizio ()
// Void function che stampa a video il menù principale //
{
printf ("\t\t\t* PIZZERIA BELLA NAPOLI *\n\t\t\t Viale Dei Giardini, 121\n\t\t\t Tel. 081-102030\n\n\n\t\t\t MENU' PRINCIPALE\n");
printf ("1. Visualizza menu' pizze\n2. Visualizza bibite\n3. Effettua ordinazione\n4. Esci\n\n");
printf ("Digita la tua scelta: ");
scelta ();
}
void scelta ()
// Void function che gestisce la scelta effettuata dall'utente nel menù principale del programma //
{
int scelta, ordinazione;
ordinazione = 0;
/* La variabile "ordinazione" viene usata come un flag. Se è impostata su zero, significa che l'utente non ha deciso di
effettuare un'ordinazione, altrimenti assume il valore uno. */
scanf ("%d", &scelta);
while ((scelta <1) || (scelta>4))
// Ciclo while che rileva l'eventuale digitazione errata da parte dell'utente di un'opzione inesistente nel menù principale. //
{
scelta = 0;
printf ("Hai digitato un valore non valido. Riprova.\n");
printf ("Digita la tua scelta: ");
scanf ("%d", &scelta);
}
if (scelta == 1) /* L'utente ha deciso di vedere il menù delle pizze */
menu_pizze (scelta, ordinazione);
if (scelta == 2) /* L'utente ha deciso di vedere il menù delle bibite */
menu_bibite (scelta);
if (scelta == 3) /* L'utente ha deciso di effettuare un'ordinazione. La variabile "ordinazione" viene impostata su uno. */
{
ordinazione = 1;
menu_pizze (scelta, ordinazione);
}
WSACleanup(); /* L'utente ha deciso di uscire dal programma. Questa istruzione termina l'utilizzo della libreria per la
gestione delle socket. */
}
void menu_pizze (int scelta, int ordinazione)
/* Questa funzione gestisce il menù delle pizze e, nel caso in cui la variabile "ordinazione" sia impostata su uno, l'ordinazione
delle stesse, chiamando la funzione "ordine" */
{
SOCKET clientsocket; // Definizione della socket per il client //
SOCKADDR_IN addr; // Per assegnare una porta ed un indirizzo IP alla socket si crea questa variabile strutturata. //
WORD wVersionRequested = MAKEWORD(2,2);
/* Il parametro MAKEWORD(2,2) della WSAStartup ricerca nel sistema la versione 2.2 della Winsock e setta la versione che
gli viene passata come quella più alta che il chiamante può usare. */
WSADATA wsaData;
int i, p;
short port; // La porta da utilizzare per la comunicazione con il server. //
char pizze [100]; // Buffer per le varie stringhe del menù delle pizze. //
WSAStartup(wVersionRequested, &wsaData);
/* Inizializzazione della libreria Socket.
wVersionRequested (param. di input) = indica la versione più alta delle socket di Windows che il chiamante può usare.
WSAData (param. di output) = un puntatore alla struct WSADATA, che deve ricevere i dettagli sulle socket di Windows.*/
port = 4000;
// La struttura SOCKADDR_IN (addr) specifica l'indirizzo famiglia, l'indirizzo ip e la porta del server con cui connettersi //
addr.sin_family = AF_INET; // Utilizzo della classe IP4 //
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
// La funzione "inet_addr" converte una stringa contenente un indirizzo IP4 nel formato adatto per la struct SOCKADDR_IN //
addr.sin_port = htons(port);
// La funzione "htons" prende un numero a 16 bit e lo converte in un numero a 16 bit nel formato IP4. //
clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/*Inizializzazione della socket per il client.
AF_INET = utilizzo della classe IP4
SOCK_STREAM = socket di tipo full-duplex. Si possono leggere e scrivere flussi di byte contemporaneamente e
indipendentemente nel canale. I dati non vengono mai perduti o ricevuti in modo duplicato.
IPPROTO_TCP = utilizzo del protocollo TCP/IP */
if (connect(clientsocket, (LPSOCKADDR)&addr, sizeof(addr)) < 0)
printf("Errore nella connessione con il Server");
//Connessione al server e, eventualmente, rilevamento dell'errore //
send(clientsocket,(char *)&scelta, sizeof(int),0);
/* Invio al server dell'opzione selezionata dall'utente, memorizzata all'interno della variabile "scelta". Nella send vengono
indicati la socket da utilizzare, la fonte del messaggio e la sua dimensione in byte. Eseguo un cast per trattare "scelta"
come una stringa, parametro standard della send. */
for (i=0; i<6; i++)
{
p = recv (clientsocket, pizze, 100,0); // Al passo i-simo, ricevo dal server l'i-sima stringa del menù delle pizze //
pizze[p]='\0'; // Aggiunge il carattere terminatore alla fine di ogni stringa ricevuta dal server. //
printf ("%s", pizze); // Stampa a video la stringa //
}
if (ordinazione == 0) // L'utente vuole solo visualizzare il menù delle pizze //
{
system ("PAUSE");
system ("CLS");
stampa_inizio();
}
else
ordine (clientsocket); // L'utente vuole ordinare. Viene passata alla function la socket attualmente in uso. //
}
void menu_bibite (int scelta)
// Questa funzione gestisce il menù delle bibite //
{
SOCKET clientsocket; // Definizione della socket per il client //
SOCKADDR_IN addr; // Per assegnare una porta ed un indirizzo IP alla socket si crea questa variabile strutturata. //
WORD wVersionRequested = MAKEWORD(2,2);
/* Il parametro MAKEWORD(2,2) della WSAStartup ricerca nel sistema la versione 2.2 della Winsock e setta la versione che
gli viene passata come quella più alta che il chiamante può usare. */
WSADATA wsaData;
int i, p;
short port; // La porta da utilizzare per la comunicazione con il server. //
char bibite [100]; // Buffer per le varie stringhe del menù delle bibite. //
WSAStartup(wVersionRequested, &wsaData);
/* Inizializzazione della libreria Socket.
wVersionRequested (param. di input) = indica la versione più alta delle socket di Windows che il chiamante può usare.
WSAData (param. di output) = un puntatore alla struct WSADATA, che deve ricevere i dettagli sulle socket di Windows.*/
port = 4000;
// La struttura SOCKADDR_IN (addr) specifica l'indirizzo famiglia, l'indirizzo ip e la porta del server con cui connettersi //
addr.sin_family = AF_INET; // Utilizzo della classe IP4 //
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
/* La funzione "inet_addr" converte una stringa contenente un indirizzo IP4 nel formato adatto per la struct SOCKADDR_IN */
addr.sin_port = htons(port);
/* La funzione "htons" prende un numero a 16 bit e lo converte in un numero a 16 bit nel formato IP4. */
clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/* Inizializzazione della socket per il client.
AF_INET = utilizzo della classe IP4
SOCK_STREAM = socket di tipo full-duplex. Si possono leggere e scrivere flussi di byte contemporaneamente e
indipendentemente nel canale. I dati non vengono mai perduti o ricevuti in modo duplicato.
IPPROTO_TCP = utilizzo del protocollo TCP/IP */
if (connect(clientsocket, (LPSOCKADDR)&addr, sizeof(addr)) < 0)
printf("Errore nella connessione con il Server");
// Connessione al server e, eventualmente, rilevamento dell'errore //
send(clientsocket,(char *)&scelta, sizeof(int),0);
/* Invio al server dell'opzione selezionata dall'utente, memorizzata all'interno della variabile "scelta". Nella send vengono
indicati la socket da utilizzare, la fonte del messaggio e la sua dimensione in byte. Eseguo un cast per trattare "scelta"
come una stringa, parametro standard della send. */
for (i=0; i<4; i++)
{
p = recv (clientsocket, bibite, 100,0); // Al passo i-simo, ricevo dal server l'i-sima stringa del menù delle bibite //
bibite[p]='\0'; // Aggiunge il carattere terminatore alla fine di ogni stringa ricevuta dal server. //
printf ("%s", bibite); // Stampa a video la stringa //
}
system ("PAUSE");
system ("CLS");
stampa_inizio();
}
void menu_bibite_ordinazione (SOCKET clientsocket)
/* Questa function stampa a video il menù delle bibite nel corso dell'ordinazione. Riceve come parametro di input la socket che è
già in uso durante l'intera procedura dell'ordine. */
{
int i, p;
char bibite [100];
for (i=0; i<4; i++)
{
p = recv (clientsocket, bibite, 100,0); // Al passo i-simo, ricevo dal server l'i-sima stringa del menù delle bibite //
bibite[p]='\0'; // Aggiunge il carattere terminatore alla fine di ogni stringa ricevuta dal server. //
printf ("%s", bibite); // Stampa a video la stringa //
}
}
void ordine (SOCKET clientsocket)
// Questa function si occupa dell'ordinazione vera e propria. //
{
int cod_pizza, cod_bibita, p;
double totale;
char pizza_scelta [50]; // Buffer per la pizza ordinata //
char bibita_scelta [50]; // Buffer per la bibita ordinata //
totale = 0;
printf ("Inserire il codice della pizza desiderata: ");
scanf ("%d", &cod_pizza);
while ((cod_pizza < 1) || (cod_pizza> 6))
// Ciclo while che rileva l'eventuale digitazione errata da parte dell'utente di una pizza inesistente //
{
cod_pizza = 0;
printf ("Codice errato. Riprova.\n");
printf ("Inserire il codice della pizza desiderata: ");
scanf ("%d", &cod_pizza);
}
send(clientsocket,(char *)&cod_pizza, sizeof(int),0);
/* Invio al server della pizza ordinata dall'utente, memorizzata all'interno della variabile "cod_pizza". Nella send vengono
indicati la socket da utilizzare, la fonte del messaggio e la sua dimensione in byte. Eseguo un cast per trattare "cod_pizza"
come una stringa, parametro standard della send. */
p = recv (clientsocket, pizza_scelta, 50,0); // Ricevo dal server la stringa relativa alla pizza ordinata.//
pizza_scelta[p]='\0'; // Aggiunge il carattere terminatore alla fine della stringa ricevuta dal server. //
printf ("%s\n", pizza_scelta); // Stampo a video la stringa //
menu_bibite_ordinazione (clientsocket);
/* Chiamata alla function "menu_bibite_ordinazione" per stampare a video il menù delle bibite, passando la socket attualmente
in uso */
printf ("Inserire il codice della bibita desiderata: ");
scanf ("%d", &cod_bibita);
while ((cod_bibita < 1) || (cod_bibita> 4))
// Ciclo while che rileva l'eventuale digitazione errata da parte dell'utente di una bibita inesistente //
{
cod_bibita = 0;
printf ("Codice errato. Riprova.\n");
printf ("Inserire il codice della bibita desiderata: ");
scanf ("%d", &cod_bibita);
}
send(clientsocket,(char *)&cod_bibita, sizeof(int),0);
/* Invio al server della bibita ordinata dall'utente, memorizzata all'interno della variabile "cod_bibita". Nella send vengono
indicati la socket da utilizzare, la fonte del messaggio e la sua dimensione in byte. Eseguo un cast per trattare "cod_bibita"
come una stringa, parametro standard della send. */
p = recv (clientsocket, bibita_scelta, 50,0); // Ricevo dal server la stringa relativa alla pizza ordinata.//
bibita_scelta[p]='\0'; // Aggiunge il carattere terminatore alla fine della stringa ricevuta dal server. //
printf ("%s\n", bibita_scelta); // Stampo a video la stringa //
recv (clientsocket, (char *)&totale, sizeof(double), 0); // Ricevo dal server il conto //
printf ("ORDINAZIONE:\nPizza: %s\nBibita: %s\nTotale: %.2f Euro\n",pizza_scelta, bibita_scelta, totale);
system ("PAUSE");
system ("CLS");
stampa_inizio();
}
Comer errori mi da una serie di undefined reference (_recv@16, _send@16, _wsastartup@8, ecc..) Come posso risolvere?
__________________
Giocattolino Micro-ATX Case Jonsbo D300 | AsRock B850M Riptide | Ryzen 7 9700X | Arctic Liquid Freezer 3 360mm | Corsair Vengeance 2x16gb 6000MHz | AMD RX9060 XT 16GB | EVGA SuperNOVA G2 650W | SSD Samsung M2 990 Pro 2TB + SSD Samsung M2 970 Plus 500GB + HDD Seagate 8TB | Yashi Pioneer 27" Curved 144Hz | Logitech G900+MSI Vigor GK50 | Logitech Z623 2.1 | --------------- Trattative sul mercatino concluse positivamente con oltre 30 utenti |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Aggiungi ws2_32.lib tra le dipendenze del progetto
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:30.



















