# file transfer problem



## virus (11. Okt 2007)

Ich hab ein Server und ein Client. die Transferieren files vom Server zum Client.

Der client sendet 

FILE /path/to/the/file

Darauf antwortete der Server mit 

--- START FILE TRANSMITION ---

nun wechselt er in binary mode und sendet zu erst 4 bytes die grösse des kommenden files und dann das file.

wenn der download fertig ist, sendet der client den nächsten FILE... befehl (aus einer Que).

nun das funktioniert perfekt beim 1. befehl
beim 2. befehl wird zwar alles korrekt gesendet aber beim empfangen stimmt die Dateigrösse nicht (also die 4 bytes werden falsch gelesen, oder es werden die falschen 4 bytes gelesen.) Was natürlich dazu führt das der download vorzeitig abbricht oder nie endet.

Server:

```
iwhile ((input = m_input.readLine()) != null && m_running) {
				if (input.startsWith("QUIT")) {
					closeClientConnection();
					break;
				} else if (input.startsWith("FILE")) {
					m_output.println("--- START FILE TRANSMITION ---");

					File f = new File(input.substring(5));
					FileInputStream fInput = new FileInputStream(f);
					OutputStream ous = m_socket.getOutputStream();
					
					
					//send file size
					long fileSize = f.length();
					byte [] b = new byte[4];
					for(int i= 0; i < 4; i++){
						b[3-i] = (byte)(fileSize >>> (i * 8));
					}
					System.out.println("Server side File Size:"+b[0]+" "+b[1]+" "+b[2]+" "+b[3]);
					ous.write(b);
					
					//send file
					byte[] nextBytes = new byte[m_socket.getSendBufferSize()];
					int bytesRead = 0;
					while ((bytesRead = fInput.read(nextBytes)) > 0) {
						ous.write(nextBytes, 0, bytesRead);
					}
				}
				
				else {
					m_output.println(input);
				}
			}
```

Client


```
while (m_connected && (msg = m_input.readLine()) != null) {

					System.out.println("Server:" + msg);

					if (msg.startsWith("--- START FILE TRANSMITION ---")) {

						

						InputStream input = m_socket.getInputStream();
						FileOutputStream output = new FileOutputStream("/download");
						byte[] outBuffer = new byte[m_socket.getReceiveBufferSize()];
						int bytesRead = 0;

						// receive fiel size
						byte[] b = new byte[4];
						long fileSize = 0;
						input.read(b);
						for (int i = 0; i < 4; i++) {
							fileSize <<= 8;
							fileSize ^= (long) b[i] & 0xFF;
						}
						System.out.println("Received File Size: "+b[0]+" "+b[1]+" "+b[2]+" "+b[3]);
						// receive file
						long transmittedSize = 0;
						while ((bytesRead = input.read(outBuffer)) > 0) {
							output.write(outBuffer, 0, bytesRead);
							transmittedSize += bytesRead;
							// abbort if file is finished
							if (transmittedSize >= fileSize)
								break;
						}
						output.close();
						//notify that the file downloaded is finished
						synchronized (m_downloadListeners) {
							for (DownloadListener dl : m_downloadListeners) {
								dl.downloadFinished(new File(download));
							}
						}
						// remove executed command
						// execute next
						synchronized (m_fileDownloadCommands) {
							m_fileDownloadCommands.removeFirst();
							if (!m_fileDownloadCommands.isEmpty())
								m_output.println((m_fileDownloadCommands.getFirst()).getCommand());
						}
					}
				}
```


----------



## tuxedo (12. Okt 2007)

Wenn du mit einem DataInput- und OutputStream arbeitest, musst du nicht selbst deinen Integer für's senden Zerlegen und nach dem Empfangen wieder zusammenbauen. Du könntest auch einen ObjectInput und OutputStream benutzen und die File durch die Leitung durchserialsieren (was für ein Wort ;-) ). Ist dann vielleicht weniger Fehleranfällig.

- Alex


----------



## virus (13. Okt 2007)

So ich hab jetzt mal ein bisschen umgebaut:

Server:

```
while ((input = m_input.readLine()) != null && m_running) {
	if (input.startsWith("QUIT")) {
		closeClientConnection();
		break;
	} else if (input.startsWith("FILE")) {
		m_output.println("--- START FILE TRANSMITION ---");
		File f = new File(input.substring(5));
		FileInputStream fInput = new FileInputStream(f);
					
		// send file size
		 ObjectOutputStream ous = new ObjectOutputStream(m_socket.getOutputStream());
		long fileSize = f.length();
		System.out.println(fileSize);
		ous.writeLong(fileSize);
		
		// send file				
		DataOutputStream dous = new DataOutputStream(m_socket.getOutputStream());
		byte[] nextBytes = new byte[m_socket.getSendBufferSize()];
		int bytesRead = 0;
		while ((bytesRead = fInput.read(nextBytes)) > 0) {
			dous.write(nextBytes, 0, bytesRead);
		}
	}
	else {
		m_output.println(input);
	}
}
```

Client:

```
while (m_connected && (msg = m_input.readLine()) != null) {

	System.out.println("Server:" + msg);

	if (msg.startsWith("--- START FILE TRANSMITION ---")) {

		synchronized (m_fileDownloadCommands) {
			m_actualLocalPath = m_fileDownloadCommands.getFirst().getLocal();
		}

		//read file size
		ObjectInputStream input = new ObjectInputStream(m_socket.getInputStream());
		long fileSize = input.readLong();
		System.out.println(fileSize);


		//read file from stream and store it to m_actualLocalPath
		FileOutputStream output = new FileOutputStream(m_actualLocalPath);
		DataInputStream dis = new DataInputStream(getSocket().getInputStream());

		byte[] outBuffer = new byte[getSocket().getReceiveBufferSize()];
		int bytesRead = 0;
		long transmittedSize = 0;
		while ((bytesRead = dis.read(outBuffer)) > 0) {
			output.write(outBuffer, 0, bytesRead);
			transmittedSize += bytesRead;

			// abbort if file is finished
			if (transmittedSize >= fileSize){
				break;
			}
		}
		output.close();

		synchronized (m_downloadListeners) {
			for (DownloadListener dl : m_downloadListeners) {
				dl.downloadFinished(new File(m_actualLocalPath));
			}
		}
		// remove executed command
		// execute next
			synchronized (m_fileDownloadCommands) {
				m_fileDownloadCommands.removeFirst();
				if (!m_fileDownloadCommands.isEmpty())
					m_output.println((m_fileDownloadCommands.getFirst()).getCommand());
			}
		}
	}
} catch (IOException ioe) {
	ioe.printStackTrace();
} finally {
	m_connected = false;
}
```

Nun hab ich aber das Problem das die applikation bei "DataInputStream dis = new DataInputStream(getSocket().getInputStream());" hängen bleibt und nicht mehr weiter macht.
Irgendwo muss hier der hund drinn sein.. ich bin jetzt schon zig stunden an dem ding und kriegs einfach nicht zum laufen :-([/code]


----------

