Programowanie rozproszone
Laboratorium 5
Celem laboratorium było nabycie umiejętności programowania przesyłu komunikatów z użyciem gniazd (sockets).
#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; } |
---|
#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; } |
---|
#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); |
---|
#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; } |
---|
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 |
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.