Jump to content
zbeng

Cum lucram cu socket-tii?

Recommended Posts

Posted

Cum lucram cu socket-tii?

                          by Zbeng

Cum 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 lucreaza

cu 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 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 */

        }

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...