I designed a file-sender program and a file-receiver program in java, to learn about the TCP file transferring over a LAN. My File-Sending Code is given below...

import java.io.*;
import java.net.*;
class filesender {
public static void main(String args[]) throws Exception
{
InputStreamReader istream = new InputStreamReader(System.in);
BufferedReader bufRead = new BufferedReader(istream);
try
{
System.out.println("Receiver's I.P:");
String serverName = bufRead.readLine();
System.out.println("File Name:");
String filename = bufRead.readLine();
Socket Socket1 = new Socket(serverName, 6789);
DataOutputStream outToServer=new DataOutputStream(Socket1.getOutputStream());
BufferedReader go=new BufferedReader(new InputStreamReader(Socket1.getInputStream()));
File file = new File(filename);
FileInputStream fin = new FileInputStream(file);
byte sendData[] = new byte[(int)file.length()];
fin.read(sendData);
outToServer.writeBytes(filename);
outToServer.writeInt(sendData.length);
outToServer.write(sendData, 0, sendData.length);
String deliveryreport = go.readLine();
System.out.println(deliveryreport);  /*Delivery report arrived from Receiver*/
Socket1.close();
}
catch (IOException err)
{ System.out.println("SENDER Error..!"); }}}

Well... my File-Receiver coding is given below...

import java.io.*;
import java.net.*;
class filereceiver {
public static void main(String args[]) throws Exception
{
try
{
String filename;
ServerSocket serverSocket = new ServerSocket(6789);
System.out.println("Waiting on Port 6789...");
Socket conSocket = serverSocket.accept();
DataInputStream dis = new DataInputStream(conSocket.getInputStream());
BufferedReader hi = new BufferedReader(new InputStreamReader(conSocket.getInputStream()));
DataOutputStream outToSender = new DataOutputStream(conSocket.getOutputStream());
int dataLength = dis.readInt();
byte[] receivedData = new byte[dataLength];
for(int i = 0; i < receivedData.length; i++)
receivedData[i] = dis.readByte();
filename = hi.readLine();
FileOutputStream fos = new FileOutputStream(filename);
fos.write(receivedData);
fos.close();
outToSender.writeBytes("File has been Sent..!");/*Delivery report to sender*/
System.out.println("File has been received..!"); /*Viewed on Receiver*/
serverSocket.close();
conSocket.close();
}
catch (IOException err)
{ System.out.println("RECEIVER Error..!"); }}}

O.K, These files were compiled executed correctly, but when I try to transfer a file, both programs give errors as below.

Sender Program given an IOException err /////////////"SENDER Error"////////////

Receiver Program said //////////"Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at filereceiver.main(filereceiver.java:17)////////////

Why these Errors occurred? Anybody could explain?

有帮助吗?

解决方案

This line because you are trying to allocate the entire stream into RAM.

byte[] receivedData = new byte[dataLength];

When your stream is small, it is OK. But for big streams, allocate a small buffer (eg. 10K) and read it in chunks.

@nos also gave a comment about server writing the file name first, followed by the file length. You have to read it in the order that the data is written. But even after you read in the correct data, you will eventually have the problem I described. You definitely need to read data in chunks and process it as you go.

In addition, since you are sending the file name to the receiver, it is good to define a proper structure/header/protocol so that the receiver can easily process the incoming data. Here is a suggestion.

  1. 1 byte to denote the file name length
  2. following bytes are the actual file name
  3. 8 bytes to denote length of contents of file.
  4. following bytes are contents of file.

At the receiver end, you read first byte to know how many bytes to read for the file name. Then you read 8 bytes to know how many bytes to read for the contents.

其他提示

Try to increase the heap memory on the receiver side using the JVM arguments like below,

-Xms512m -Xmx1g  -XX:PermSize=512m  -XX:MaxPermSize=1g
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top