Ich weiß, dass ähnliche Fragen existieren, aber ich habe keine von ihnen passend für mein Problem gefunden. Ich habe ein Android-Gerät (API 15 - Android Version 4.0.4) und einen Linux-Rechner mit Arch Linux. Die Idee war, eine Verbindung zwischen dem Server (C-Programm) und dem Client (Android-App) herzustellen, damit ich Dateien austauschen konnte. Außerdem unterstützt der Server parallele Verbindungen und erfordert Authentifizierung. Die Android-App muss 3 Verbindungen zum Server erstellen (mit 3 verschiedenen Ports, also 3 AsyncTask-s mit Multi-Threading). Zwei davon sind für parallele Hintergrundprozesse und 1 für die eigentliche Dateiübertragung. Ich habe einen Code erstellt, der gut auf dem Emulator funktioniert (Android KitKat OS), aber beim Testen auf meinem eigenen Telefon funktioniert es nicht. Ich werde meinen Code posten, und ich möchte einen Rat von Ihnen, wenn das möglich ist. Vielen Dank.Verwendung von TCP für Dateiübertragung zwischen Java (Android-Client) und C (PC-Server - Linux)
Dies ist der Code läuft auf Android-Geräten ... BUFFSIZE ist 1024 und es ist eine globale Variable. Ich habe versucht, es auf viele Werte zu setzen und keiner von ihnen funktionierte für mich. Dateigröße ist früher im Code festgelegt und hat immer den richtigen Wert also keine Sorgen darüber :)
InputStream is = socket.getInputStream();
FileOutputStream fs = new FileOutputStream(target);
int u;
byte[] jj = new byte[BUFFSIZE];
long overall = 0, percent = 0;
try {
while (overall < filesize && mRun) {
u = is.read(jj, 0, BUFFSIZE);
if (u == -1) break;
fs.write(jj, 0, u);
overall += u;
percent = overall*100/filesize;
}
fs.flush();
fs.close();
is.close();
socket.close();
} catch (IOException ex) {
// There were no exceptions while testing
// There is some code here that deals with the UI
// which is not important
}
Und dies ist der C-Code ...
for (;;)
{
/* First read file in chunks of BUF_SIZE bytes */
unsigned char buff[BUFFER]={0};
int nread = fread(buffer,1,BUFFER, input);
printf("Bytes read %d \n", nread);
/* If read was success, send data. */
if(nread > 0)
{
printf("Sending \n");
write(sockfd, buffer, nread);
}
/*
* There is something tricky going on with read ..
* Either there was error, or we reached end of file.
*/
if (nread < BUFFER)
{
if (feof(input))
printf("End of file\n");
if (ferror(input))
printf("Error reading\n");
break;
}
}
ich diesen Code getestet haben viele Male, sogar mit Telnet und es funktionierte ziemlich gut. Aber ich bin mir nicht sicher über den Java-Code.
Also, warum funktioniert es nicht? Nun, was ich bisher weiß ist, dass einige Dateien beschädigt sind. Sagen wir einfach, wenn ich eine mp3-Datei mit der Größe von 4MB übertrage, würde 3,99 gesendet werden und die restlichen 0,01 würden irgendwo in der Mitte der Datei verloren gehen, ohne Grund! Wenn du das beschädigte mp3 spielst, kannst du erkennen, dass manche Teile (wie alle 10 Sekunden) du "off-beat" gehst .. Als ob da ein kleines Geräusch wäre, das dann übersprungen wird. Die resultierende Datei ist kürzer für ungefähr 10 000 Bytes als das Original (aber das hängt von der tatsächlichen Dateigröße ab. Sie verlieren immer einen kleinen Prozentsatz der Datei und das bedeutet, dass die while-Schleife nie beendet wird - der Download-Prozess wird nie beendet, weil die Sockets blockieren und der Client wartet auf weitere Bytes, die nie empfangen werden). Was ich glaube, ist, dass von einem 1024 Byte langen Puffer manchmal 1000 statt des vollen 1024-Puffers verwendet werden Größe, die zum Verlust von 24 Bytes führt. Ich sage nicht, dass dies die tatsächlichen Zahlen sind, aber das ist nur etwas in meinem Kopf; Damit liege ich wahrscheinlich falsch. Ich konnte den ganzen Code nicht mit dir teilen, weil er wirklich lang ist, also entschied ich mich, stattdessen die Funktionen zu verwenden, die den Download-Prozess betreffen.
Ja, aber warum wird meine Datei dann nicht empfangen? Es funktioniert gut mit Textdateien und wenn ich es debugge.Es schlägt mit etwas größeren Dateien fehl. Es überspringt von Zeit zu Zeit ein paar Bytes. Lass uns einfach so tun, als wäre dies die ganze Datei: 12345 .. Es liest 123 und dann 5 .. Es überspringt die Zahl 4 und wenn es ans Ende der ganzen Datei kommt, hängt es dort, weil es erwartet, dass mehr Bytes gelesen werden (um genau zu sein - Nummer 4) .. Dies ist, was mit großen Dateien passiert und ich kann nicht herausfinden, wo das eigentliche Problem ist. – user3752782