Jump to content
Dr4k3

Cum lucram cu socket-tii

Recommended Posts

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

}

CREDITS TO SACX

Link to comment
Share on other sites

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...