Criminal Posted July 12, 2006 Report Posted July 12, 2006 1. Ce este un socket ? Pai mai "babeste" spus este un canal de comunicatie ! Unu la mana exista mai multe tipuri de socketuri : 1. SOCK_STREAM : bidirectional , sigur 2. SOCK_DGRAM : bidirectional , nesigur (pachetele sar putea sa nu se mai intoarca 3. SOCK_RAW : folosit pentru "dedesupturi" 4. SOCK_PCK : cred ca este cel mai vechi (recomandabil a nu se folosi Doi la mana exista mai multe tipuri de domeni (ce fac domenile astea ? impun niste reguli de comunicatie socketurilor !) 1. AF_UNIX - domeniu de tip UNIX; 2. AF_INET - domeniu de tip Internet; 3. AF_RAW - domeniu de tip RAW 2. Cum creeam un socket ? connect = socket(domeniu,tip,protocol); Ex. Vrem sa cream un socket prin care sa ne putem lega la un port ! connect = socket(AF_INET,SOCK_STREAM,0); Easy ? Apropo connect este un integer care semnifica descriptorul . (da, da , exact ca la fisiere); 3. Cum asociem un nume socketului ? Pentru identificare socketului de catre procese acesta are nevoie de un nume. Cand folosim domeniul internet (AF_INET) acest nume este compus din adresa masini server cat si cea a masini client cat si a porturilor lor . Ex. bind(connect,nume,lungime nume) 4. Cum ne conectam ? Depinde ce vrem sa facem . Daca vrem client vom folosi functia connect : connect(descriptor, nume_socket, lungime_nume_socket); unde descripor este descriptorul socket-ului , nume_socket este socketul si lungime nume socket este sizeof(lungime_socket); ))) Daca vrem server folosim listen(decriptor,numar_conexiuni) unde descripor este descriptorul socket-ului iar numar connexiuni este numarul de conexiuni admise de server Ex. listen(connect,5); Dupa care folosim functia accept ca sa "acceptam" cererile catre server Ex. accept(connect,nume_socket, lungime_nume_socket); 5. Cum transmitem si receptionam date ? Sub unix (mai precis sub linux) avem fucntile read si write ! sunt exact aceleasi functii pe care le folosim si la citirea si scrierea in fisiere! Sub windoze lucrurile se complica cam un pic dar nu mult ! Adica se folosesc alte 2 functii : send(connect,buffer,sizeof(buffer),flaguri); recv(connect,buffer,sizeof(buffer),flaguri); unde flaguri reprezinta : MSG_PEEK - la un nou apel al functiei read() sau recv(), va fi citit din nou acelasi mesaj; MSG_OOB - este folosit pentru transmisia mesajelor cu prioritate maxim??; MSG_DONTROUTE - trimite datele f??r?? pachetele de rutare; (celelalte optiuni ale functilor send si recv sunt mura'n gura , nu ? 6. Cum inchidem un socket ? O data cu close(connect); (exact ca la fisiere) sau cu shutdown(connect,tip de inchidere); unde tip de inchidere poate fi 0: nu se main pot citi date prin socket 1: nu se mai pot trimite date 2: nu se mai pot receptiona date 7. Practica : 1. Vom pune in practica un client care drept sa spun l-am facut pt. linux dar cred ca nu veti avea probleme sa il compilati si in Visual C++ (special am folosit functile send si recv) 2. Vedeti ca programul de fata nu a fost compilat niciodata Am facut si eu ceva reciclare de cod , am scris ceva de mana si uite ce o iesit 1. Exemplu de client: #include<all_headers.h> ))))))) #define PORT 23 #define MAXLINE 4096 client(int socket) { char recvline[MAXLINE],sendline[maxline]; for( ; ; ){ if (recv(socket,recvline,MAXLINE,0)==0){ printf("server terminated prematurely ! n"); exit(1); } if (strncmp(recvline,"HALLO",5)==0){ strncpy(sendline,"Ce faci smechere ?",strlen("Ce faci smechere ?")); // rea ii lenea asta )) send(socket,sendline,strlen(sendline),0); } } } int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; if (argc != 2) err_quit("usage: client <IPaddress>"); ifdef comentariu Creeam socketul ... endif sockfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); inet_pton(AF_INET, argv[1], &servaddr.sin_addr); ifdef comentariu Dupa crearea socket-ului neconectam ! endif connect(sockfd, (struct sockaddr_in *) &servaddr, sizeof(servaddr)); ifdef comentariu Predam socketul unei functii care stie ce sa faca cu el endif client(sockfd); // in functa asta faceti numa send-uri si recv-uri ifdef comentariu Inchidem socketul endif close(sockfd); exit(0); } Ok ! acuma sa dam drumu si la un server : (asta o fost compilat si o functionat perfect (sub linux (Visual c++ cred eu ca nu stie de fork ! cred ca asta ar fi singurul inconvenient sub windows) 2. Exemplu de server : #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <errno.h> #include <stdlib.h> #include <signal.h> #ifdef LINUX #include <sys/time.h> #endif #define SERV_PORT 115 //#define DEBUG void sig_chld(int signo) { pid_t pid; int stat; pid = wait(&stat); printf("child %d terminatedn", pid); return; } int main(void) { int listenfd, connfd; pid_t childpid; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; void sig_chld(int); char remotestring[512],check[32]; strcpy(remotestring,"SErVer Open and Readyn"); remotestring[22]=0; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); listen(listenfd, 1024); signal(SIGCHLD, sig_chld); for ( ; ; ) { clilen = sizeof(cliaddr); if ( (connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0) { if (errno == EINTR) continue; /* ianpoi la for */ else printf("accept error"); } if ( (childpid = fork()) == 0) { /* procesul copil */ send(connfd, remotestring, strlen(remotestring), 0); for({ recv(connfd, check, 511, 0); #ifdef DEBUG printf("check%s",check); #endif if (strncmp(check,"Close",5)==0) break; if (strncmp(check,"Hallo",5)==0) send(co nnfd,"Hallo ! I am the servern", 24, 0); } close(listenfd); /* inchide socketul care asculta */ exit(0); } close(connfd); /* inchidem socketul parinte */ } Quote
limbpizdit Posted July 13, 2006 Report Posted July 13, 2006 dragutz; ii criminal tutorialu 'ca sa sa fiu carcotas iti bag si o critica - nu puteai sa-l si formatezi ? Quote