[Linux]
Witam! Napisałem dwa programy: klient i serwer działające tak, że klient ma wysyłać do serwera plik w postaci pakietów danych (rozm. przyjąłem 256 bitów) a serwer zapisywać w pliku o przesłanej przez klienta nazwie (podobny mechanizm jak w scp, z tym że między zaufanymi użytkownikami, więc nie ma potrzeby podawać hasła). Komunikacja sieciowa działa jak należy (więc nie będę przytaczać w kodzie) ale nie mam pomysłu jak zrobić synchronizację między klientem a serwerem. Z resztą sami zobaczcie:
serwer.c
main(int argc, char *argv[])
{
int fd, newfd, fd_file, pid, serverLength, clientLength, number=0;
struct sockaddr_in serverAddr, clientAddr;
char buf[MAX]="\0", *dot_conv, fname[FILE_MAX_NAME]="\0";
/*Stworzenie serwera i przypisanie fd*/
fd = create_serwer_socket();
listen(fd, 5);
for (;;)
{
clientLength = sizeof(clientAddr);
/*oczekiwanie na polaczenie klienta*/
if ((newfd = accept(fd, (struct sockaddr *) &clientAddr, &clientLength)) == -1)
{
perror("Blad accept");
exit(1);
}
/*utworzenie procesu potomnego*/
if ((pid = fork()) == -1)
{
perror("Blad fork");
exit(1);
}
/*obsluga polaczenia przez proces potomny*/
else if (pid == 0)
{
close(fd);
/*Pobierz nazwę pliku*/
strcpy(fname, "./");
read(newfd, fname, FILE_MAX_NAME);
strcat(fname, buf);
printf("%s\n", fname); ************
/*otwieranie pliku do przepisania do bufora*/
fd_file = open(fname, O_WRONLY|O_APPEND|O_CREAT|O_EXCL);
if(fd_file == -1)
{
perror("open");
exit(2);
}
dot_conv = inet_ntoa(clientAddr.sin_addr);
printf("\n%s Progress:\n", dot_conv);
/*Tu trzeb synchronizacji!"*/ **************
/*Pobieraj i zapisuj do pliku*/
while(read(newfd, buf, MAX) >= 0)
{
fsync(newfd); //możliwe że zbędne
if(write(fd_file, buf, MAX) == -1)
perror("write");
printf("/");
number++;
}
close(fd_file);
printf("Done...\n Total number of packages send: %d\n", number);
exit(0);
}
close(newfd);
}
}
klient.c
main(int argc, char *argv[])
{
int fd, fd_file, n=1, status;
off_t length=0;
char buf[MAX]="\0", fname[FILE_MAX_NAME];
if (argc != 3)
{
fprintf(stderr, "Poprawne wywolanie: %s adres plik\n", argv[0]);
exit(1);
}
/*łączenie z serwerem*/
strcpy(fname, argv[2]);
fd = create_client_socket(argv[1]);
/*otwieranie pliku do przepisania do bufora*/
fd_file = open(fname, O_RDONLY);
if(fd_file == -1)
{
perror("open");
exit(2);
}
/*Wysłanie nazwy pliku*/
if(write(fd, fname, FILE_MAX_NAME) == -1)
perror("write");
while((status=pread(fd_file, buf, MAX, length)) > 0)
{
length = n*MAX;
n++;
/*kopiowanie i wysyłanie danych*/
if(write(fd, buf, MAX) == -1)
perror("write");
}
if(status == -1)
perror("pread");
close(fd_file);
close(fd);
exit(0);
}
oczywiście używam łącze strumieniowe. Gwiazdkami (mam nadzieję że widać ;)) oznaczyłem linijkę gdzie jest wypisywany komunikat o nazwie pliku i gdzie są wysyłane dane. Program działa jak na razie w ten sposób, że wyświetla na konsoli część tekstu (pewnie 2 pakiet - czyli ten z danymi a nie z nazwą) i wypisuje: open: No such file or directory.
Dzięki z góry za pomoc!