zbeng Posted September 5, 2006 Report Posted September 5, 2006 Cum lucram cu socket-tii?              by ZbengCum lucram cu socket-tii ?Cred ca de multe ori va-ti intrebat cum lucreaza BO2K sau exploiturile !(Sper sa nu va dau ideii Pai chiar asa de complicat asa nu poate fi ! hai sa vedem cum naiba se lucreazacu socket-tii !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 intoarca3. 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 comunicatiesocketurilor !)1. AF_UNIX - domeniu de tip UNIX;2. AF_INET - domeniu de tip Internet;3. AF_RAW - domeniu de tip RAW2. 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 compusdin 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 socketulsi 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 serverEx. listen(connect,5);Dupa care folosim functia accept ca sa "acceptam" cererile catre serverEx. accept(connect,nume_socket, lungime_nume_socket);5. Cum transmitem si receptionam date ? Sub unix (mai precis sub linux) avem fucntile read si write ! suntexact 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 alte2 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 fi0: nu se main pot citi date prin socket1: nu se mai pot trimite date2: nu se mai pot receptiona date7. 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 iesit1. Exemplu de client:#include<all_headers.h> )))))))#define PORT 23#define MAXLINE 4096client(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); } }}intmain(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 elendif    client(sockfd);    // in functa asta faceti numa send-uri si recv-uriifdef comentariu Inchidem socketulendif  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 inconvenientsub 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 DEBUGvoid 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
DarkWizzard Posted September 6, 2006 Report Posted September 6, 2006 http://beej.us/guide/bgnet/output/html/index.htmlAici gasiti un tutorial mai mare. Quote
!_30 Posted September 6, 2006 Report Posted September 6, 2006 http://www.cs.cf.ac.uk/Dave/C/node28.html#...000000000000000asta e super , tot ce trebuie desrep socketi , IPC , RPC-uri , share memory .. dar tebuie sa ai baza calumea , cu pointeri , etc.. va descurcati voi . Quote