Hej:)
Chciałbym przesłać plik z za pomoca gniazd BSD w linuxie. Mam klienta który otwiera plik, zapisuje jego objetość do zmiennej, oblicza ile razy bedzie musiał przebiec pętle for (objetosc / 512), w której za każdym razem pobiera z pliku blok o dlugosci 512 bajtow i wysyła je do serwerowi. Serwer otwiera plik do zapisu, odbiera kolejne bloki bajtow od klienta i zapisuje je do otwartego pliku - tu też wszystko dzieje się w pętli for. Z początku, by zobaczyć, czy działa wziąłem jakiś plik *.jpg obliczylem ile razy musi zostać przebiegnięta pętla, i zapisałem ją w kodzie serwera. Wszystko działało - plik się kopiował. Teraz zrobiłem tak, żeby pierwsza wysyłka zawierała liczbę iteracji i coś się popsuło. Serwer tworzy plik, ale nie można go otworzyć: "Błąd przy interpretacji pliku z obrazem JPEG (Not a JPEG file: starts with 0x4a 0x46)"
Poniżej wklejam kod, który działa, po odkomentowaniu zakomentowanych linii się sypie.
Kod jest długi ale zmiana jest potrzebna w miejscu po nawiązaniu połączenia. Nie przejmujcie się funkcją itos() jest ona pomocnicza i zamienia mi int-a na c-stringa. Oczywiście jeśli ktoś spróbuje mi pomóc to przy kopiowaniu swojego pliku niech zmieni liczbe iteracji w serwerze na odpowiednia (podłoga z objetosc pliku / 512 + 1), oraz nazwe otwieranego pliku w kliencie. Najpierw odpala się serwer podając w linii komend nr portu, potem klienta również podając nr portu (serwer działa na lokalnym ip 127.0.0.1). Z góry dzięki, chociażby za rzucenie okiem :) Luknijcie sami, bo ja już nie wiem co jest nie tak :P
Klient:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <signal.h>
void itos(char* bufor, int i)
{
memset(bufor,0,sizeof(bufor));
int k = 1, l = 0, m = 0; char zmiana;
while(i) {
k = 10*k; l = i % k; m = (l / (k/10)); i -= l;
switch (m) {
case 0: strcat(bufor, "0"); break; case 1: strcat(bufor, "1"); break; case 2: strcat(bufor, "2"); break;
case 3: strcat(bufor, "3"); break; case 4: strcat(bufor, "4"); break; case 5: strcat(bufor, "5"); break;
case 6: strcat(bufor, "6"); break; case 7: strcat(bufor, "7"); break; case 8: strcat(bufor, "8"); break;
case 9: strcat(bufor, "9"); break;
}
}
m = strlen(bufor);
if (m % 2 == 0) { k = m / 2; } else { k = (m / 2) + 1; }
--m;
for(l=0; l < k; l++) { char zmiana = bufor[l]; bufor[l] = bufor[m-l]; bufor[m-l] = zmiana; }
}
int main(int argc, char * argv[]) {
int z;
int dlugosc;
int gniazdo;
int size;
int j,i;
size_t przeczytano;
unsigned int port;
char bufor_a[512];
char bufor_b[8];
char adres_IP[20];
struct sockaddr_in adres;
if (argc >= 2) {
port = atoi(argv[1]);
} else {
printf("Na jakim porcie nasluchuje serwer? ");
scanf("%u", &port);
}
if ((gniazdo = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("blad socket()");
return 1;
}
memset(&adres, 0, sizeof(adres));
adres.sin_family = AF_INET;
adres.sin_port = ntohs(port);
adres.sin_addr.s_addr = inet_addr("127.0.0.1");
dlugosc = sizeof(adres);
if((connect(gniazdo, (struct sockaddr *) &adres, dlugosc)) == -1) {
printf("blad connect()");
return 1;
}
FILE * pFile = fopen("spodek.jpg","rb");
fseek(pFile, 0, SEEK_END);
size = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
j = (size / sizeof(bufor_a)) + 1;
itos(bufor_b, j);
// send(gniazdo, bufor_b, strlen(bufor_b), 0);
// memset(bufor_a, 0, 512);
for(i=0; i < j; i++) {
przeczytano = fread(bufor_a, 1, sizeof(bufor_a), pFile);
send(gniazdo, bufor_a, przeczytano, 0);
memset(bufor_a, 0, 512);
}
fclose(pFile);
close(gniazdo);
return 0;
}
Serwer:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <signal.h>
int main(int argc, char * argv[]) {
int z;
unsigned int port; /*port serwera*/
struct sockaddr_in serwer_adres; /*adres serwera*/
struct sockaddr_in klient_adres; /*adres serwera*/
int dlugosc; /*dlugosc adresu serwera/klienta*/
int serwer_gniazdo; /*gniazdo serwera*/
int klient_gniazdo; /*gniazdo klienta*/
int sesja_gniazdo; /*gniazdo polaczenia*/
FILE * odczyt = NULL; /*strumien odczytu*/
FILE * zapis = NULL; /*strumien zapisu*/
if (argc >= 2) {
port = atoi(argv[1]); /*port pobrany z linii polecen*/
}
else {
printf("Na jakim porcie nasluchiwac?");
scanf("%u", &port);
}
if ((serwer_gniazdo = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("blad socket()");
return 1;
}
memset(&serwer_adres, 0, sizeof(serwer_adres));
/*tworzenie adresu serwera*/
serwer_adres.sin_family = AF_INET;
serwer_adres.sin_port = ntohs(port);
serwer_adres.sin_addr.s_addr = inet_addr("127.0.0.1");//INADDR_ANY;
dlugosc = sizeof(serwer_adres);
/*wiazanie adresu z gniazdem*/
if (bind(serwer_gniazdo, (struct sockaddr *) &serwer_adres, dlugosc) == -1) {
printf("blad bind()\n");
return 1;
}
/*nasluchiwanie*/
if ((z = listen(serwer_gniazdo, 10)) == -1 ) {
printf("blad listen()");
return 1;
}
dlugosc = sizeof(klient_adres);
if((sesja_gniazdo = accept(serwer_gniazdo, (struct sockaddr *) &klient_adres, &dlugosc )) == -1) {
printf("blad accept()");
return 1;
}
odczyt = fdopen(sesja_gniazdo, "r");
if(!odczyt) {
fclose(odczyt);
}
zapis = fdopen(dup(sesja_gniazdo), "w");
if(!zapis) {
fclose(zapis);
}
char buffer_a[512];
char buffer_b[8];
size_t odebrano;
FILE * plik;
int i,j;
// fread(buffer_b, 1, sizeof(buffer_b), odczyt);
// buffer_b[strlen(buffer_b)-1] = '\0';
// j = atoi(buffer_b);
plik = fopen("kopia.jpg", "wb");
// tu w tej pętli po odkomentowaniu powyższych zakomentowanych wierszy powinna być w miejsce 38 zmienna j
for(i=0; i < 38; i++) {
odebrano = fread(buffer_a,1,sizeof(buffer_a),odczyt);
fwrite(buffer_a,1,odebrano,plik);
}
fclose(plik);
fclose(zapis);
shutdown(fileno(odczyt), SHUT_RDWR);
fclose(odczyt);
return 0;
}