PR lab 4

Programowanie rozproszone

Laboratorium 4

Cel

Celem laboratorium było nabycie umiejętności programowania przesyłu komunikatów z użyciem gniazd (sockets).

  1. Kod źródłowy

    1. klient

#include <string.h>

#include <arpa/inet.h>

#include "sock.h"

#include "sock.c"

int main(int argc,char *argv[]){

int scid,i=0,j=0,size;

char mbuffer[100];

char lbuffer[70];

struct sockaddr_in address;

memset(&address,0,sizeof(address));

address.sin_family=AF_INET;

address.sin_port=htons(17000);

address.sin_addr.s_addr=inet_addr("149.156.136.215");

scid=sccreate(AF_INET, SOCK_STREAM, 0);

if(scid==-1)

exit(1);

if(scconnect(scid,(struct sockaddr *) (&address), sizeof(address))==-1)

exit(2);

while(1)

{

fprintf(stdout,"Podaj komunikat do wyslania:\t");

if(fgets(lbuffer,sizeof(lbuffer),stdin)==NULL)

fprintf(stderr,"fgets eof...");

size=strlen(lbuffer);

mbuffer[size-1]='\0';

fprintf(stdout,"Komunikat do wyslania:\t\t%s\n",mbuffer);

if(scsend(scid, &mbuffer, sizeof(mbuffer), 0)==-1)

exit(3);

if(mbuffer[0]=='0')

{

close(scid);

fprintf(stdout,"Client disconnected\n");

return 0;

}

if(screcv(scid, &mbuffer, sizeof(mbuffer), 0)==-1)

exit(4);

fprintf(stdout,"%i: Odebrany komunikat:\t%s\n",getpid(),mbuffer);

}

return 0;

}

serwer

#include <arpa/inet.h>

#include "sock.h"

#include "sock.c"

char mbuffer[100];

void powme()

{

long int j = atoi(mbuffer);

sprintf(mbuffer,"%ld",j*j);

}

int main(int argc,char *argv[]){

int scid, xscid;

struct sockaddr_in address,xaddress;

socklen_t address_len=sizeof(address);

socklen_t xaddress_len=sizeof(xaddress);

address.sin_family=AF_INET;

address.sin_port=htons((short)17000);

address.sin_addr.s_addr=INADDR_ANY;

scid=sccreate(AF_INET, SOCK_STREAM, 0);

if(scid==-1)

exit(1);

if(scbind(scid, (struct sockaddr *) (&address), address_len)==-1)

exit(2);

if(sclisten(scid, 10)==-1)

exit(3);

fprintf(stdout,"Server is up and running\n");

while(1)

{

if((xscid=scaccept(scid, (struct sockaddr *) &xaddress, &xaddress_len))==-1)

exit(4);

switch(fork())

{

case -1:

fprintf(stderr,"errno: %i : ",errno);

perror("FORK ERROR");

break;

case 0:

close(scid);

while(1)

{

if(screcv(xscid, &mbuffer, sizeof(mbuffer), 0)==-1)

exit(5);

fprintf(stdout,"Tresc otrzymanego komunikatu: %s\n",mbuffer);

if(mbuffer[0]=='0')

{

fprintf(stdout,"Client terminate connection with server\n");

close(xscid);

return 0;

}

powme();

fprintf(stdout,"Tresc wysylanego komunikatu: %s\n",mbuffer);

if(scsend(xscid, &mbuffer, sizeof(mbuffer), 0)==-1)

exit(6);

}

break;

default:

close(xscid);

}

}

return 0;

}

sock.h – własna obsługa błędów socketów

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <errno.h>

#include <sys/socket.h>

struct sockaddr_un

{

unsigned short sun_family;

char sun_path[108];

};

int sccreate(int, int, int);

int scconnect(int, const struct sockaddr *, socklen_t);

int scbind(int, const struct sockaddr *, socklen_t);

int scaccept(int, struct sockaddr *, socklen_t *);

int sclisten(int, int);

ssize_t screcv(int, void *, size_t, int);

ssize_t scsend(int, const void *, size_t, int);

sock.c – własna obsługa błędów socketów

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <errno.h>

#include <sys/socket.h>

int sccreate(domain, type, protocol)

{

int scid;

if((scid=socket(domain, type, protocol))==-1)

{

fprintf(stderr,"errno: %i : ",errno);

perror("socket error");

}

return scid;

}

int scconnect(int socket, const struct sockaddr *address, socklen_t address_len)

{

int value;

if((value=connect(socket, address, address_len))==-1)

{

fprintf(stderr,"errno: %i : ",errno);

perror("connect error");

}

return value;

}

int scbind(int socket, const struct sockaddr *address, socklen_t address_len)

{

int value;

if((value=bind(socket, address, address_len))==-1)

{

fprintf(stderr,"errno: %i : ",errno);

perror("bind error");

}

return value;

}

int scaccept(int socket, struct sockaddr *address, socklen_t *address_len)

{

int value;

if((value=accept(socket, address, address_len))==-1)

{

fprintf(stderr,"errno: %i : ",errno);

perror("accept error");

}

return value;

}

int sclisten(socket, backlog)

{

int value;

if((value=listen(socket, backlog))==-1)

{

fprintf(stderr,"errno: %i : ",errno);

perror("listen error");

}

return value;

}

ssize_t screcv(int socket, void *buffer, size_t length, int flags)

{

ssize_t value;

int err;

if((value=recv(socket, buffer, length, flags))==-1)

{

err=errno;

fprintf(stderr,"%i-errno\n",errno);

perror("recv error");

while(err==EINTR)

{

if((value=recv(socket, buffer, length, flags))==-1)

{

err=errno;

perror("recv error - 2");

}

else

return value;

}

return -1;

}

return value;

}

ssize_t scsend(int socket, const void *buffer, size_t length, int flags)

{

int value, err;

if((value=send(socket, buffer, length, flags))==-1)

{

err=errno;

fprintf(stderr,"%i-errno\n",errno);

perror("send error");

while(err==EINTR)

{

if((value=send(socket, buffer, length, flags))==-1)

{

err=errno;

perror("send error - 2");

}

else

return value;

}

return -1;

}

return value;

}

Przykłady działania

lunar@andLinux:~/windows/lab4$ ./lab4-klient

Podaj komunikat do wyslania: 2

Komunikat do wyslania: 2

2730: Odebrany komunikat: 4

Podaj komunikat do wyslania: 81

Komunikat do wyslania: 81

2730: Odebrany komunikat: 6561

Podaj komunikat do wyslania: 43

Komunikat do wyslania: 43

2730: Odebrany komunikat: 1849

Podaj komunikat do wyslania: 0

Komunikat do wyslania: 0

Client disconnected

lunar@Moon:~ /lab4: ./lab4-serwer

Server is up and running

Tresc otrzymanego komunikatu: 2

Tresc wysylanego komunikatu: 4

Tresc otrzymanego komunikatu: 81

Tresc wysylanego komunikatu: 6561

Tresc otrzymanego komunikatu: 43

Tresc wysylanego komunikatu: 1849

Tresc otrzymanego komunikatu: 0

Client terminate connection with server

Wnioski

Stworzona para programów (klient – serwer) pokazuje nam jak łatwo można przekazać wykonanie obliczeń na zewnętrzne maszyny (tym samym odciążenie stacji klienta), które w zamyśle mają do dyspozycji większą liczbę zasobów. Postępowanie takie rekompensuje nieraz nawet użycie mniej wydajnych algorytmów.
Podczas tego laboratorium używaliśmy gniazd i w przeciwieństwie do poprzednich zajęć, podczas których używaliśmy interfejsu MPI dostarczającego funkcje wysokiego poziomu, teraz używaliśmy podstawowych zapytań umożliwiających na gniazdach. Dzięki temu zagłębiliśmy się bardziej w implementacyjne szczegóły interakcji pomiędzy dwiema maszynami, a nie tylko ograniczyli się do wykorzystania gotowych interfejsów MPI, które przeprowadzały za nas całe zarządzanie gniazdami.


Wyszukiwarka

Podobne podstrony:
PR lab 3
PR lab 1
PR lab 2
PR LAB Cw4 Kinematyka prędkości i przyśpieszeń
PR lab 5
PR lab 3
PR LAB Cw4 Kinematyka prędkości i przyśpieszeń
Pr 1st 1 1 m01 lab id 382178 Nieznany
gri2 lab cwiczenia z podstaw pr Nieznany
[PKC][LAB][Ostatnia laborka][Pr Nieznany
statyczna pr rozcia, Budownictwo pcz, referaty wytrzymka lab
Lab 1 wyznaczanie pr śr
Pr 1st 1 1 m12 lab
spis lab I sem 2010
PR CYW PR ROP WYKLAD 26
Stany nagle w położnictwie PR
Pr UE Zródła prawa (IV 2013)
III WWL DIAGN LAB CHORÓB NEREK i DRÓG MOCZ
PR CYW PR ROP WYKLAD 28

więcej podobnych podstron