PR lab 5

Programowanie rozproszone

Laboratorium 5

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

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#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];

size_t result;

FILE *handle;

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("127.0.0.1");

scid=sccreate(AF_INET, SOCK_STREAM, 0);

if(scid==-1)

exit(1);

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

exit(2);

if(!(handle=fopen("filetowrite","wb")))

{

perror("File open error");

exit(1);

}

while(1)

{

result=screcv(scid, &mbuffer, sizeof(mbuffer), 0);

if(result==-1)

{

fclose(handle);

close(scid);

return 1;

}

else if(result == 0)

{

fclose(handle);

close(scid);

fprintf(stdout,"File transfer completed\n");

return 0;

}

fprintf(handle , "%s", mbuffer);

}

return 0;

}

serwer

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#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);

}

void sendmenow(int scid)

{

FILE *handle;

long lSize;

size_t result;

handle = fopen("filetosend","rb");

while(1)

{

result = fread (&mbuffer,sizeof(char),100,handle);

mbuffer[result]='\0';

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

{

if(fclose(handle))

fprintf(stderr,"Error: Handle close error\n");

exit(9);

}

if(result < 100)

{

if(fclose(handle))

fprintf(stderr,"Error: Handle close error\n");

close(scid);

fprintf(stdout,"File transfer completed\n");

return;

}

}

}

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);

sendmenow(xscid);

return 0;

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/lab5$ ./p10-klient

File transfer completed

lunar@andLinux:~/windows/lab5$ ./p10-klient

File transfer completed

lunar@andLinux:/mnt/win/lab5$ ./p10-serwer

Server is up and running

File transfer completed

File transfer completed

Wnioski

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