View Full Version : Uffa ..i socket..
uffanoia
12-03-2005, 18:42
Ciao
qualcuno potrebbe dirmi perche' questo stupido programma non va?
in teoria Il client si connette al server che risponde con uno stupido messaggio.
La connessione sembra avvenire,ma il client non stampa quello che dovrebbe
---------------------------------------------------
server.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <winsock.h>
#define PORT 12345
#define BL 1024
main() {
int sock, client_len, fd;
char buffer[BL];
struct sockaddr_in server, client;
#ifdef WIN32
WSADATA wsaData;
WSAStartup (0x0101,&wsaData);
#endif
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock <0) {
perror("creazione del socket fallita");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY); /* accetta da qualunque sua interfaccia */
server.sin_port = htons(PORT);
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) <0) {
perror("bind socket fallita");
exit(2);
}
listen(sock, 15);
while(1) {
client_len = sizeof(client);
if( (fd=accept(sock, (struct sockaddr *)&client, &client_len))<0) {
perror("accept fallita");
exit(3);
}
printf("Comunicazione in arrivo\n");
sprintf(buffer, "Ciao sono il Server di prova\n\0\0");
write(fd, buffer, strlen(buffer)+1);
close(fd);
}
}
---------------------------------------------------------------------------
Client.c
#include <winsock.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define PORT 12345
#define BL 1024
main(argc, argv) int argc; char *argv[]; {
int sock, server_len, count;
char buffer[BL];
struct hostent *host;
struct sockaddr_in server, client;
#ifdef WIN32
WSADATA wsaData;
WSAStartup (0x0101,&wsaData);
#endif
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock <0) {
perror("creazione del socket fallita");
exit(1);
}
host = gethostbyname(argv[1]);
if(host == NULL) {
perror("host inesistente");
exit(2);
}
server_len = sizeof server;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr=htonl(INADDR_ANY);
memcpy(&server.sin_addr.s_addr, host->h_addr, host->h_length);
if(connect(sock, (struct sockaddr *)&server, sizeof(server))<0){
perror("Errore connect");
exit(3);
}
printf("Connessione Fatta\n");
while((count=read(sock, buffer, BL))>0) {
printf("%d %s\n", count, buffer);
}
close(sock);
}
-------------------------------------
grazie
ciao
Uffanoia
Fenomeno85
12-03-2005, 19:27
server
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <winsock.h>
#define PORT 12345
#define BL 1024
#define localhost "127.0.0.1"
int main() {
int sock, client_len, fd;
char buffer[BL];
struct sockaddr_in sad, cad;
#ifdef WIN32
WSADATA wsaData;
WSAStartup (0x0101,&wsaData);
#endif
memset ((char*)&sad,0,sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr(localhost);
sad.sin_port = htons ((u_short)PORT);
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock <0) {
perror("creazione del socket fallita");
exit(1);
}
if(bind(sock, (struct sockaddr *)&sad, sizeof(sad)) <0) {
perror("bind socket fallita");
exit(2);
}
listen(sock, 15);
while(1) {
printf ("\nIn attesa di client\n");
client_len = sizeof(cad);
if( (fd=accept(sock, (struct sockaddr *)&cad, &client_len))<0) {
perror("accept fallita");
exit(3);
}
printf("Comunicazione in arrivo\n");
char string[] = "Ciao sono il server di prova.\n";
send (fd, string, sizeof (string), 0);
closesocket (fd);
}
closesocket(sock);
}
client
#include <winsock.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define PORT 12345
#define BL 1024
#define localhost "127.0.0.1"
int main(int argc, char* argv[]) {
int sock, server_len, count;
char buffer[BL];
struct hostent *host;
struct sockaddr_in server, client;
#ifdef WIN32
WSADATA wsaData;
WSAStartup (0x0101,&wsaData);
#endif
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock <0) {
perror("creazione del socket fallita");
exit(1);
}
host = gethostbyname(argv[1]);
if(host == NULL) {
perror("host inesistente");
exit(2);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(localhost);
server.sin_port = htons ((u_short)PORT);
if(connect(sock, (struct sockaddr *)&server, sizeof(server))<0){
perror("Errore connect");
exit(3);
}
printf("Connessione Fatta\n");
while((count=recv(sock, buffer, sizeof(buffer),0))>0) {
printf("%d %s\n", count, buffer);
}
closesocket(sock);
system ("PAUSE");
return (EXIT_SUCCESS);
}
~§~ Sempre E Solo Lei ~§~
guardando il codice velocemente ho notato che per inviare e ricevere i dati usi read e write, che non č del tutto sbagliato, ma il dubbio mi viene perche quelle funzioni si usano per scrivere i file a basso livello senza buffer(ogni chiamata corrisponde ad un accesso diretto al disco), e quindi non so con certezza se funzioni o meno, io ti consilio di usare le funzioni send e recv che funzionano sicuramente.
send(int socket,voids * buff,int buflen,int fleg)//per inviare normalmente puoi impostare il flag a 0
recv(int socket,voids * buff,int buflen,int fleg)//per ricevere normalmente puoi impostare il flag a 0
uffanoia
12-03-2005, 19:51
Grazie!!
Ora funziona perfettamente !
Ma per cosa sta PF_INET ?
--
La funzione che ho usato
memcpy(&server.sin_addr.s_addr, host->h_addr, host->h_length);
e' Inutile?
---
memset ((char*)&sad,0,sizeof(sad));
cancella la "struttura"? perche' bisogna farlo prima se subito dopo la si "riempie"?
---
Perchč l'uso di read e write non sono corrette?
--
Al posto di send e recv si potrebbero usare
sendto() e
recvfrom()?
---
ciao
uffanoia
Fenomeno85
12-03-2005, 20:03
PF_INET sta per il protocollo va bene anche AF_INET ... ma logicamente sarebbe meglio scrivere il primo nella creazione del socket.
memcpy che hai fatto va bene se vuoi usare gethostbyname te lo ho tolto per velocitā mia.
cancellare la struttura č per la compatibilitā con la struttura sockaddr. si č discusso un paio di giorni fa.
sendto e recvfrom dovrebbero forse andare mai provato
~§~ Sempre E Solo Lei ~§~
uffanoia
12-03-2005, 20:20
Ok ,tutto chiaro
grazie mille!
Buona giornata
Ciao
uffanoia
Fenomeno85
12-03-2005, 20:21
de nada
~§~ Sempre E Solo Lei ~§~
pavimento
13-03-2005, 11:51
ciao
secondo me per usare read e write devi condividere il buffer mettendolo in un .h
Gia' che ci sono chiedo..
Ma se invece di un messaggio stringa volessi rispondere con un intero come faccio visto che il buffer č dichiarato char * , e lo devo passare a send e recv come char *?
La funzione select() a cosa serve?
Se voglio mandare messaggi in broadcast,o mandare messaggi a piu client, come devo fare/cosa devo usare?
Fenomeno85
13-03-2005, 12:00
un modo sarebbe quello di usare una union
~§~ Sempre E Solo Lei ~§~
uffanoia
13-03-2005, 13:50
Ciao,
Per gli interi con union funziona sicuramente.
per la select www.lilik.it/~mirko/gapil/gapilsu251.html
Per il broadcast credo si debba usare UDP,eliminando accept(),connect() e utilizzando solo sendto e recvfrom().
ciao
uffanoia
Futuregames
13-03-2005, 14:04
scusate io nn ho mai capito a cosa serve il socket?
pavimento
13-03-2005, 14:31
grazie
e quindi che differenze ci sono con udp(che č poi sto udp?)?
non esiste alcun modo(corretto) per usare read e write invece di send e recv?
uffanoia
13-03-2005, 15:24
Allora..molto velocemente ..grosso modo..
Un socket č definita come l'stremita' di un canale di comunicazione.
Una coppia di processi che comunica attraverso una rete usa una coppia di socket,una per ogni processo,e ogni socket č identificata da un indirizzo IP concatenato a un numero di porta.
Le architetture client-server sono implementate ,solitamente,usando le socket.
Il server attende le richieste dei client ,stando in ascolto sulle porte;quando riceve una richiesta ,se accetta la connessione proveniente dalla socket del client ,si stabilisce la comunicazione.
La differenza č appunto č eliminare accept(),connect() e utilizzare solo sendto() e recvfrom().
Non so se esiste un modo per usare read e write,ma credo di si.
comunque funzionano benissimo anche send e recv .
Comunque se trovi un modo potresti postarlo..
ciao
uffanoia
pavimento
13-03-2005, 18:21
Ma se volessi contattare piu client con i socket normali non
si potrebb
e fare un ciclo for nella chiamata socket();
for(i=0;I<n;i++){
sock = socket(PF_INET, SOCK_STREAM, 0);
}
in questo modo ci sarebbe un socket per ogni client.O no?
Fenomeno85
13-03-2005, 18:42
dovresti creare dei figli
~§~ Sempre E Solo Lei ~§~
pavimento
13-03-2005, 19:20
utilizzando la fork()?
quindi come verrebbe?
while(1){
...
..
pid=fork();
if(pid==0){
fai_quello_che_devi-fare;
}
else close}
invia_risposta();}
???
Se si leggono le specifiche delle funzioni read č write, queste vanno ad eseguire un accesso diretto al dispositivo senza alcun buffer o cosa del genere, il socket invece possiede un buffer dove vengono scritti e letti i dati, quindi non si possono utilizzare funzioni non bufferizate su buffer e le read e write non funzionano, come invece funzionano le FileRead e FileWrite di windows.
Ciao..
pavimento
13-03-2005, 20:48
Ma in teoria essendo
int read(int fildes,void* buf,size_t nbyte);
Legge n bytes dal file associato a fildes copiandoli nella zona di memoria a partire dall'indirizzo "buf";restituisce il numero di bytes effettivamente letti.
int write(int fildes,const void* buf,size_t nbyte);
Scrive nbyte nel file associato a "fildes" copiandoli nella zona di memoria a partire dall 'indirizzo "buf";restituisce il numero di bytes scritti.
dovrebbero leggere/scrivere i bytes dal/nel contenuto di buf.
Quindi se uso una write scrivo nel buffer e per leggerlo uso una read.Non capisco perche' non possa andare bene?
?????
Per Windows devi usare send e recv...per Linux puoi usare send e recv o read e write...
pavimento
14-03-2005, 19:45
ah ho capito
grazie
ciao
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.