Problem z przesylaniem pliku(client-server) LINUX

0

Witam,
mam problem z programem do przesyłania plików. Przeważnie przerywa działanie przed przesłaniem całego pliku. Nie mam pojęcia co robię nie tak. Prosze o pomoc.

server:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

#define MAX_ROZ 512

int main(void) {

   int gniazdo, polaczenie, connection = 0, rozmiar_pliku =0, roz, rozmiar;
   double tmp2;
   struct sockaddr_in data;
   socklen_t laddr_len;
   unsigned char buff[MAX_ROZ+1],roz_buff[5],nazwa_pliku[128] = {"output"};
   FILE *plik;

   gniazdo = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

   //Aby nie było problemu z bindem
   setsockopt(gniazdo, SOL_SOCKET, SO_REUSEADDR, &rozmiar, sizeof(rozmiar));

   if (gniazdo == -1) {
      perror("socket");
      exit(1);
   }

   memset(&data, 0, sizeof(struct sockaddr));

   data.sin_family = PF_INET;
   data.sin_port = htons(6677);
   data.sin_addr.s_addr = htonl(INADDR_ANY);

   polaczenie = bind(gniazdo, (struct sockaddr*)&data, sizeof(struct sockaddr));
   if (polaczenie == -1) {
      close(gniazdo);
      perror("bind ----->");
      exit(1);
   }
   
   printf("\nConnected\n");

   polaczenie = listen(gniazdo, 1);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("listen");
      exit(1);
   }

   laddr_len = sizeof(struct sockaddr);

   while ((connection = accept(gniazdo, (struct sockaddr*)&data, &laddr_len)) == 0);
   
// Wyslanie powitania do clienta
   strcpy(buff, "\nWitaj na serverze suboxa i Filipa.\n\n\n");
   polaczenie = send(connection, buff, strlen(buff), 0);
   if (polaczenie == -1) {
      close(gniazdo);
      close(connection);
      perror("send");
      exit(1);
   }

   memset(buff, 0, MAX_ROZ);

   // odbieramy rozmiar pliku
   polaczenie = recv(connection, buff, MAX_ROZ, 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("recv-rozmiar");
      exit(1);
   }

   printf("rozmiar: %s\n", buff);

   rozmiar_pliku = atoi(&buff[0]);

   // odbieramy rozszerzenie pliku
   memset(buff, 0, MAX_ROZ);
   polaczenie = recv(connection, buff, MAX_ROZ, 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("recvrozszerzenie");
      exit(1);
   }

   printf("rozszerzenie: %s\n", buff);

   strcat(nazwa_pliku,buff);
   printf("%s",nazwa_pliku);
   plik = fopen(nazwa_pliku,"wb+");
   if( plik == NULL) {
      perror("fopen");
      exit(1);
   }

   tmp2 = 0;
   while(rozmiar_pliku > tmp2){
      tmp2 += MAX_ROZ;
      memset(buff, 0, MAX_ROZ);
      polaczenie = recv(connection, roz_buff, 4, 0);
      if(polaczenie == -1) {
         close(gniazdo);
         perror("recv: rozmiar przesanego pakietu--->>");
         exit(1);
      }

      roz = atoi(&roz_buff[0]);
      polaczenie = recv(connection, buff, roz, 0);
      if (polaczenie == -1) {
         close(gniazdo);
         perror("recv: odbierany pakiet--->>");
         exit(1);
      }
   
      fwrite(buff,sizeof(unsigned char),roz,plik);
      //printf("%d\n",roz);
   }

   memset(buff, 0, MAX_ROZ);
   strcpy(buff, "\nPlik zostal przeslany na server.\n\n\n");
   polaczenie = send(connection, buff, MAX_ROZ, 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("send");
      exit(1);
   }

   close(polaczenie);
   close(gniazdo);
   return 0;
}

client:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

#define MAX_ROZ 512

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

   int gniazdo, polaczenie,roz;
   double tmp2, sec, nsec;
   struct sockaddr_in dane;
   unsigned char buff[MAX_ROZ],roz_buff[4], nazwa_pliku[128], ip_adress[16];
   FILE *plik;
   struct stat bufor;
   char *tmp;

   struct timespec start, stop;

   if(argc == 2 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h") || !strcmp(argv[1],"?") || !strcmp(argv[1],"/?"))){
      printf("\n***HELP***\n\n");
      exit(0);
   }

   if(argc == 1){
      printf("Uzywamy domyslnego lokalnego adresu: 127.0.0.1\n");
      strcpy(ip_adress,"127.0.0.1");
      printf("Podaj nazwe pliku: ");
      fgets(nazwa_pliku, 128, stdin);
   }
   else
      if (argc == 2){
         printf("\nUzywamy domyslnego lokalnego adresu: 127.0.0.1\n");
         strcpy(ip_adress,"127.0.0.1");
         printf("Przesylamy plik: %s",argv[1]);
         strcpy(nazwa_pliku,argv[1]);
      }
      else{
         strcpy(ip_adress,argv[2]);
         printf("\nUzywamy adresu IP: %s\n",ip_adress);
         printf("Przesylamy plik: %s",argv[1]);
         strcpy(nazwa_pliku,argv[1]);
      }
      

   gniazdo = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
   if (gniazdo == -1) {
      perror("socket");
      exit(1);
   }

   memset(&dane, 0, sizeof(struct sockaddr));

   dane.sin_family = PF_INET;
   dane.sin_port = htons(6677);
   dane.sin_addr.s_addr = inet_addr("127.0.0.1");

   polaczenie = connect(gniazdo, (struct sockaddr*)&dane, sizeof(struct sockaddr));
   if (polaczenie == -1) {
      close(gniazdo);
      perror("connect");
      exit(1);
   }

   memset(buff, 0, MAX_ROZ);

   polaczenie = recv(gniazdo, buff, MAX_ROZ, 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("recv");
      exit(1);
   }
   printf("%s",buff);

   memset(buff, 0, MAX_ROZ);

   plik = fopen(nazwa_pliku,"rb");
   if( plik == NULL) {
      perror("fopen");
      exit(1);
   }

// Odczytujemy rozmiar pliku i wysylamy go do servera
   stat(nazwa_pliku,&bufor);
   sprintf(buff,"%d",bufor.st_size);
   printf("Rozmiar pliku: %s\n",buff);
   polaczenie = send(gniazdo, buff, strlen(buff), 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("send: Calkowity rozmiar pliku--->>");
      exit(1);
   }
         
//wysylanie rozszerzenia pliku
   memset(buff, 0, MAX_ROZ);
   tmp = strstr(nazwa_pliku,".");
   strcpy(buff,tmp);
   //printf("\n%s\t%d\n",buff,strlen(buff));
   polaczenie = send(gniazdo, buff, MAX_ROZ, 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("send: Calkowity rozmiar pliku--->>");
      exit(1);
   }
   
   clock_gettime(CLOCK_REALTIME, &start);
   tmp2 = 0;
   while(bufor.st_size > tmp2){
      tmp2 += MAX_ROZ;
      roz = fread(buff,sizeof(unsigned char), MAX_ROZ, plik);
      sprintf(roz_buff,"%d",roz);
      //printf("%d\n",roz);
      polaczenie = send(gniazdo, roz_buff, 4, 0);
         if (polaczenie == -1) {
            close(gniazdo);
            perror("send: rozmiar wyslanego pakietu--->>");
            exit(1);
        }
                
      polaczenie = send(gniazdo, buff, roz, 0);
      if (polaczenie == -1) {
         close(gniazdo);
         perror("send: wyslany pakiet--->>");
         exit(1);
      }
   }
   
   polaczenie = recv(gniazdo, buff, MAX_ROZ, 0);
   if (polaczenie == -1) {
      close(gniazdo);
      perror("recv: potwierdzenie");
      exit(1);
   }

   clock_gettime(CLOCK_REALTIME, &stop);
   printf("\n%s",buff);

   sec = stop.tv_sec - start.tv_sec;
   nsec = stop.tv_nsec - start.tv_nsec;
   printf("Czas przesylania pliku: %.2lf sec\nSrednia predkosc: %.2lf kB/s\n", sec + nsec/(double)1000000000L,bufor.st_size/(sec + nsec/(double)1000000000L)/1024);

   close(gniazdo);
   return 0;
}

Kompilacja:

gcc server.c -o server
gcc client.c -lrt -o client
0

tak to jest jak sie nie czyta mana

man 2 send ...

MSG_NOSIGNAL
              Requests  not to send SIGPIPE on errors on stream oriented sockets when the other end breaks the con-
              nection. The EPIPE error is still returned.

man 7 signal ...

SIGPIPE      13       Term    Broken pipe: write to pipe with no readers
0

jeśli możesz to wyjaśnij coś więcej z

man 7 signal ...
SIGPIPE 13 Term Broken pipe: write to pipe with no readers

Zmiana flagi w send na MSG_NOSIGNAL nic nie dała.

Z góry dzięki

0

z tego co widze to ty wysylasz rozmiar fragmentu a potem ten fragment...
troche to bezsensu jesli leci to przez tcp...
wyslij najpierw rozmiar pliku a potem tylez bajtow i bedzie ok...

1 użytkowników online, w tym zalogowanych: 0, gości: 1