Jestem odrobinę bliżej rozwiązania. Wywaliłem z kodu wszystko, a zostawiłem samą komunikację z serwerem w celu skopiowania pliku. Zostało mi:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define MAX_BUF 1024 //maksymalna pojemnosc bufora
#define MAX_CODE 11 //maksymalna dlugosc kodu bledow
#define MAX_NAME 24 //maksymalna dlugosc nazwy pliku (np. app.exe)
#define MAX_ADDR 231 //maksymalna dlugosc adresu pliku
#define MAX_CMD 512 //maksymalna dlugosc komendy
struct plik {
char nazwa[MAX_NAME];
char adres[MAX_ADDR];
};
void wskazSerwer(struct sockaddr_in *);
void wskazPlik(struct plik *);
int wyslijZlecenie(char, int, struct sockaddr_in *, struct plik *);
int szukaj(char *, char);
/*
*
*/
int main(int argc, char** argv) {
struct plik file;
struct sockaddr_in addr;
char bufor[MAX_BUF], zadanie = 'k';
int sockd, statusRead, statusWrite, i;
void *ptr;
FILE *fp;
//Faza przygotowan
addr.sin_family = AF_INET;
inet_aton("127.0.0.1", &addr.sin_addr);
addr.sin_port = htons(6666);
file.adres[0] = '\0';
file.nazwa[0] = '\0';
sockd = socket(AF_INET, SOCK_STREAM, 0);
if (sockd == -1) {
perror("Socket nie zostal utworzony\n");
exit(1);
}
statusRead = connect(sockd, (struct sockaddr *) & addr, sizeof (addr));
if (statusRead == -1) {
perror("Blad polaczenia\n");
exit(1);
}
memset(bufor, 0, MAX_BUF);
bufor[0] = 'k'; //kod zlecenia
ptr = &file;
//zbuforowanie i wyslanie struktury z danymi pliku, ktorego zlecenie dotyczy
for (i = 0; i<sizeof (struct plik); i++) {
bufor[i + 1] = *((char *) (ptr + i));
}
statusWrite = write(sockd, bufor, MAX_BUF);
if (statusWrite == -1) {
perror("Blad polaczenia\n");
exit(1);
}
//zamkniecie gniazda dla pisania
shutdown(sockd, SHUT_WR);
printf("Wyslano zlecenie do serwera\n");
//opracowanie odpowiedzi serwera
memset(bufor, 0, MAX_BUF);
statusRead = read(sockd, bufor, MAX_CODE);
if (statusRead == -1) {
perror("Blad polaczenia\n");
exit(1);
}
if (zadanie == 'k') {
printf("Rozpoczynam kopiowanie pliku...\n");
statusRead = 1;
/* DEBUG czy musi byc osobny katalog??
strcpy(cmd, "mkdir ");
strcat(cmd, plik->adres);
strcat(cmd, " >/dev/null 2>&1");
//jesli katalog nie istnieje -utworz go
system(cmd);*/
fp = fopen("wtf.txt", "w");
while (statusRead != 0) {
memset(bufor, 0, MAX_BUF);
statusRead = read(sockd, bufor, MAX_BUF);
if (statusRead == -1) {
perror("Blad polaczenia\n");
exit(1);
}
statusWrite = fwrite(bufor, 1, statusRead, fp);
if (statusWrite == -1) {
perror("Blad zapisu w pliku\n");
exit(1);
}
printf("%s", bufor);
}
close(fp);
printf("Plik skopiowano!\n");
}
close(sockd);
return 1;
}
Po skompilowaniu - działa. No to zacząłem z pełnej aplikacji usuwać zbedne partie kodu, stopniowo, sprawdzając, który kod po wyrzuceniu powoduje że aplikacja działa. Doszedlem do magicznego momentu, kiedy moj plik wygląda tak:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define MAX_BUF 1024 //maksymalna pojemnosc bufora
#define MAX_CODE 11 //maksymalna dlugosc kodu bledow
#define MAX_NAME 24 //maksymalna dlugosc nazwy pliku (np. app.exe)
#define MAX_ADDR 231 //maksymalna dlugosc adresu pliku
#define MAX_CMD 512 //maksymalna dlugosc komendy
struct plik {
char nazwa[MAX_NAME];
char adres[MAX_ADDR];
};
void wskazSerwer(struct sockaddr_in *);
void wskazPlik(struct plik *);
int wyslijZlecenie(char, int, struct sockaddr_in *, struct plik *);
int szukaj(char *, char);
/*
*
*/
int main(int argc, char** argv) {
struct plik file;
struct sockaddr_in addr;
char bufor[MAX_BUF], zadanie = 'k';
int sockd, statusRead, statusWrite, i;
void *ptr;
FILE *fp;
//Faza przygotowan
addr.sin_family = AF_INET;
inet_aton("127.0.0.1", &addr.sin_addr);
addr.sin_port = htons(6666);
file.adres[0] = '\0';
file.nazwa[0] = '\0';
while (1) {
//system("clear");
printf("\n\tProjekt SKM - Zadanie 25\n");
printf("\t\tKlient\n\n");
printf("Serwer: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
printf("Adres pliku: \"%s\"\n", file.adres);
printf("Plik: \"%s\"\n\n", file.nazwa);
printf("1. Wskaz serwer\n");
printf("2. Wskaz adres pliku\n");
printf("3. Pobierz plik z Internetu za posrednictwem serwera\n");
printf("4. Sprawdz status transmisji plikow na serwerze\n");
printf("5. Skopiuj plik z serwera\n");
printf("6. Wyjscie\n");
getchar();
sockd = socket(AF_INET, SOCK_STREAM, 0);
if (sockd == -1) {
perror("Socket nie zostal utworzony\n");
exit(1);
}
statusRead = connect(sockd, (struct sockaddr *) & addr, sizeof (addr));
if (statusRead == -1) {
perror("Blad polaczenia\n");
exit(1);
}
memset(bufor, 0, MAX_BUF);
bufor[0] = 'k'; //kod zlecenia
ptr = &file;
//zbuforowanie i wyslanie struktury z danymi pliku, ktorego zlecenie dotyczy
for (i = 0; i<sizeof (struct plik); i++) {
bufor[i + 1] = *((char *) (ptr + i));
}
statusWrite = write(sockd, bufor, MAX_BUF);
if (statusWrite == -1) {
perror("Blad polaczenia\n");
exit(1);
}
//zamkniecie gniazda dla pisania
shutdown(sockd, SHUT_WR);
printf("Wyslano zlecenie do serwera\n");
//opracowanie odpowiedzi serwera
memset(bufor, 0, MAX_BUF);
statusRead = read(sockd, bufor, MAX_CODE);
if (statusRead == -1) {
perror("Blad polaczenia\n");
exit(1);
}
if (zadanie == 'k') {
printf("Rozpoczynam kopiowanie pliku...\n");
statusRead = 1;
/* DEBUG czy musi byc osobny katalog??
strcpy(cmd, "mkdir ");
strcat(cmd, plik->adres);
strcat(cmd, " >/dev/null 2>&1");
//jesli katalog nie istnieje -utworz go
system(cmd);*/
fp = fopen("wtf.txt", "w");
while (statusRead != 0) {
memset(bufor, 0, MAX_BUF);
statusRead = read(sockd, bufor, MAX_BUF);
if (statusRead == -1) {
perror("Blad polaczenia\n");
exit(1);
}
statusWrite = fwrite(bufor, 1, statusRead, fp);
if (statusWrite == -1) {
perror("Blad zapisu w pliku\n");
exit(1);
}
printf("%s", bufor);
}
close(fp);
printf("Plik skopiowano!\n");
}
close(sockd);
}
return 1;
}
Jeżeli się przyjrzycie, lub w notepadzie odpalicie porównywanie plików to okaże się, że jedyna różnica między tymi kodami to fakt, że w tym, ktory nie działa jest pętla while(1) do wyświetlenia menu.
// <cpp> </cpp> [mf]