In school we have a project where we have to send a file from server to a client. The problem we have is that when we transfer the file from the server to the client, the server shutsdown the connection. Here is our code so far:
Client:
public static void main(String argv[]) throws Exception {
int port = 8888; //default
if (argv.length
> 0) {
port = Integer.parseInt(argv[0]);
}
Socket clientSocket = new Socket("127.0.0.1", port);
PrintStream outToServer = new PrintStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
File f = new File("dictionaryPart.txt");
String serverCommand = inFromServer.readLine().toLowerCase();
while (serverCommand != null) {
System.out.println(serverCommand);
switch (serverCommand) {
case "velkommen":
outToServer.println("Hej");
break;
case "file":
f = copy(clientSocket, f);
String matches = CrackerCentralized.checkFile(f);
System.out.println(matches);
outToServer.println(matches);
break;
}
serverCommand = inFromServer.readLine().toLowerCase();
}
}
public static File copy(Socket clientSocket, File f) {
try {
int filesize = 2022386;
int bytesRead;
int currentTot = 0;
byte[] buffer = new byte[filesize];
InputStream is = clientSocket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(buffer, 0, buffer.length);
currentTot = bytesRead;
while (bytesRead != -1) {
bytesRead = is.read(buffer, currentTot, (buffer.length - currentTot));
if (bytesRead >= 0) {
currentTot += bytesRead;
}
}
bos.write(buffer, 0, currentTot);
bos.flush();
bos.close();
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
return f;
}
Server:
try {
PrintStream outToClient = new PrintStream(connection.getOutputStream());
OutputStream os = connection.getOutputStream();
BufferedInputStream input = new BufferedInputStream(new FileInputStream(f));
outToClient.println("file");
final byte[] buffer = new byte[(int) f.length()];
input.read(buffer, 0, buffer.length);
os.write(buffer, 0, buffer.length);
os.write(-1);
os.flush();
System.out.println(connection.isClosed());
os.close();
System.out.println(connection.isClosed());
} catch (IOException ex) {
Logger.getLogger(SocketController.class.getName()).log(Level.SEVERE, null, ex);
}
I am aware of WHY the connection keeps on closing. We close the socket's output by writing
output.close();
But I don't know in what other way we must try to do this to make the server keep listening for the clients answer (match/no match), so that the server knows wether it should send more files or if the client was successful.. Is it even possible to send at file without shutting down the connection to the server? I've googled all day the last 2 days without any luck
Thanks for reading and for your help.
In order to implement what you are asking, you need to establish a communication protocol that the server and client understand. Something needs to be transmitted that says, "I'm starting to send information to you," and something that says, "I'm done sending stuff." There could be more -- such as information delimiting (e.g. Mime multipart form boundary). But at a minimum, you need the start and stop tokens.
Expanding on that: Look at the code in its simplest form: server:loop{write()} -> client:loop{read()}. Closing the stream on the server-side sends the -1 value to the client, which is usually consumed as the stop signal. If you want to maintain the connection indefinitely, and write to the client at different times, something has to be sent that says, "This transaction is complete". The following is pseudo-ish code -- freehand, not compiled.
// SERVER
private Socket socket; // initialized somewhere
private static final byte[] STOP = "</COMMS>".getBytes();
public void sendData(byte[] bytes) throws IOException{
OutputStream out = socket.getOutputStream();
if(bytes != null){
out.write(bytes,0,bytes.length);
}
out.write(STOP);
} // notice we exit the method without closing the stream.
// CLIENT
private Socket socket; // initialized somewhere
private static final byte[] STOP = "</COMMS>".getBytes();
private static final int BUFFER_SIZE = 1024 << 8;
private InputStream in;
public byte[] receiveData(){
if(in == null){
in = socket.getInputStream();
}
byte[] content;
byte[] bytes = new byte[BUFFER_SIZE];
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){ // normal termination
if(receivedStop(bytes,bytesRead)){ // see if stopped
removeStopBytes(bytes,bytesRead); // get rid of the STOP bytes
content = buildContent(content,bytes,bytesRead); // transfer bytes to array
break;
}
content = buildContent(content,bytes,bytesRead); // transfer bytes to array
}
return content;
}
Again, that was freehand and not compiled or tested. I'm sure it's not fully correct but hopefully you get the gist. The server writes content but never closes the stream. The client reads the stream looking for the STOP content, building up the final content until the stop is reached.
Thanks to madConan for the reply, it gave me a good idea of how to do it. I will post my code here, so others can use it in future.
SERVER CODE
public void run() {
try {
PrintStream outToClient = new PrintStream(connection.getOutputStream());
OutputStream os = connection.getOutputStream();
BufferedInputStream input = new BufferedInputStream(new FileInputStream(f));
outToClient.println("file");
copy(input, os, f);
System.out.println(connection.isClosed());
} catch (IOException ex) {
Logger.getLogger(SocketController.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static void copy(final InputStream is, final OutputStream os, File f) throws IOException {
final byte[] stop = "stop".getBytes();
final byte[] buffer = new byte[(int) f.length()];
is.read(buffer, 0, buffer.length);
os.write(buffer, 0, buffer.length);
os.write(stop);
os.flush();
}
CLIENT CODE
public static File recieveData(Socket clientSocket, File f) {
try {
InputStream in = clientSocket.getInputStream();
FileOutputStream output = new FileOutputStream(f);
byte[] content;
byte[] bytes = new byte[1024 << 8];
int bytesRead;
while (true) {
if (recieveStop(f)) {
removeStop(f);
break;
}
bytesRead = in.read(bytes);
output.write(bytes, 0, bytesRead);
}
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
return f;
}
public static boolean recieveStop(File f) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
String currentLine;
String lastLine = "";
while ((currentLine = br.readLine()) != null) {
lastLine = currentLine;
}
if (lastLine.equals("stop")) {
return true;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
br.close();
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
return false;
}
public static void removeStop(File f) {
try {
RandomAccessFile raFile = new RandomAccessFile(f, "rw");
long length = raFile.length();
raFile.setLength(length - 4);
raFile.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
Hope this will help others with the same problem.
Related
I can transfer the files but when I want to open them it says that the file is corrupted (because its 0 bytes long). T
When I start the TCPServer it waits for clients and accepts them and then sends the file to them. The client recives the file (but not all of it I assume ?) When I tried this with a picture.png that is 10 kb it worked. With anything else, it does not. I also did port forwarding (else the client couldnt get the file)
THIS IS THE TCPSERVER:
import java.io.*;
import java.net.*;
class TCPServer {
private final static String fileToSend = "C:/Users/Tim/Desktop/P&P/Background music for P&P/Rock.wav";
public static void main(String args[]) {
while (true) {
ServerSocket welcomeSocket = null;
Socket connectionSocket = null;
BufferedOutputStream outToClient = null;
try {
welcomeSocket = new ServerSocket(3222);
connectionSocket = welcomeSocket.accept();
outToClient = new BufferedOutputStream(
connectionSocket.getOutputStream());
} catch (IOException ex) {
// Do exception handling
}
if (outToClient != null) {
File myFile = new File(fileToSend);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = null;
try {
fis = new FileInputStream(myFile);
} catch (FileNotFoundException ex) {
// Do exception handling
}
BufferedInputStream bis = new BufferedInputStream(fis);
try {
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0, mybytearray.length);
outToClient.flush();
outToClient.close();
connectionSocket.close();
// File sent, exit the main method
return;
} catch (IOException ex) {
// Do exception handling
}
}
}
}
}
HERE IS THE TCP CLIENT:
import java.io.*;
import java.net.*;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.SourceDataLine;
class TCPClient {
private final static String serverIP = "123.123.123.123";
private final static int serverPort = 3222;
private final static String fileOutput = "C:/Users/Daniel/Desktop/check.wav";
public static void main(String args[]) {
while (true) {
byte[] aByte = new byte[1024];
int bytesRead;
Socket clientSocket = null;
InputStream is = null;
try {
clientSocket = new Socket(serverIP, serverPort);
is = clientSocket.getInputStream();
} catch (IOException ex) {
// Do exception handling
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (is != null) {
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fos = new FileOutputStream(fileOutput);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(aByte, 0, aByte.length);
do {
baos.write(aByte);
bytesRead = is.read(aByte);
} while (bytesRead != -1);
bos.write(baos.toByteArray());
bos.flush();
bos.close();
clientSocket.close();
} catch (IOException ex) {
// Do exception handling
}
}
// Music is played here
try {
AudioInputStream input = AudioSystem
.getAudioInputStream(new File(fileOutput));
SourceDataLine line = AudioSystem.getSourceDataLine(input
.getFormat());
line.open(input.getFormat());
line.start();
byte[] buffer = new byte[1024];
int count;
while ((count = input.read(buffer, 0, 1024)) != -1) {
line.write(buffer, 0, count);
}
line.drain();
line.stop();
line.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Refactored your client code a little bit:
no need for the ByteArrayOutputStream when already using a BufferedOutputStream
use bytesRead for byte array offset
This worked for me:
if (is != null)
{
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try
{
fos = new FileOutputStream(new File(fileOutput));
bos = new BufferedOutputStream(fos);
while ((bytesRead = is.read(aByte)) != -1)
{
bos.write(aByte, 0, bytesRead);
}
bos.flush();
bos.close();
clientSocket.close();
} catch (IOException ex)
{
ex.printStackTrace();
}
}
I need to copy and paste dynamically incrementing log file data from FTP Server to local drive.
The below program I used can only do the copying one time. And not in the incremental manner.
public class ReadFtpFile {
public static void main(String[] args) throws UnknownHostException {
String server = "myIP";
int port = 20;
String user = "username";
String pass = "password";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// APPROACH #2: using InputStream retrieveFileStream(String)
String remoteFile2 = "/folder/myfile.log";
File downloadFile2 = new File("F:/myfolder/mylogfile.log");
OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2));
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
byte[] bytesArray = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(bytesArray)) != -1) {
outputStream2.write(bytesArray, 0, bytesRead);
}
Boolean success = ftpClient.completePendingCommand();
if (success) {
System.out.println("File #2 has been downloaded successfully.");
}
outputStream2.close();
inputStream.close();
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
The log file data in the FTP server is growing for every second.I need to update the local file with new data in the FTP.
Replace the lines
OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2));
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
with
ftpClient.setRestartOffset(downloadFile2.length());
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2, true));
This will check if the file already exists and, if so, download only the new data. If you need to do this periodically, add a loop around the whole try-catch block.
You need to update your code with Java threads and combine while loops to schedule this program for desired time.
String remoteFile2 = "/folder/myfile.log";
File downloadFile2 = new File("F:/myfolder/mylogfile.log");
OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2));
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
byte[] bytesArray = new byte[4096];
int bytesRead = -1;
int minutecount=0;
while(minutecount==120){
while ((bytesRead = inputStream.read(bytesArray)) != -1) {
outputStream2.write(bytesArray, 0, bytesRead);
}
// Here i sceduled for every 1 minute
Thread.sleep(60*1000);
minutecount++;
}
Boolean success = ftpClient.completePendingCommand();
if (success) {
System.out.println("File #2 has been downloaded successfully.");
}
outputStream2.close();
inputStream.close();`
I created a program which will send a file to the server or to clients
my problem is I have 2 clients and they both need to send a file to the server
what happens is that the server is able to receive the file only from 1 client(the one who sends the file first)
how can I resolve this problem?
here's my code:
SERVER
private void sendFile(File file)throws IOException
{
Socket socket = null;
String host = "127.0.0.1";
String receiver=txtReceiver.getSelectedItem().toString();
int port=0;
if(receiver=="Client1")
{
host="127.0.0.2";
port=4441;
}
else if(receiver=="Client2")
{
port=4442;
host="127.0.0.3";
}
else if(receiver=="Server")
{
port=4440;
host="127.0.0.1";
}
socket = new Socket(host, port);
//File file = new File("Client.txt");
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
int count;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
}
public static void main(String args[]) throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(4440);
} catch (IOException ex)
{
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
try
{
socket = serverSocket.accept();
} catch (IOException ex)
{
System.out.println("Can't accept client connection. ");
}
try
{
is = socket.getInputStream();
bufferSize = socket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex)
{
System.out.println("Can't get socket input stream. ");
}
try
{
fos = new FileOutputStream("C:\\Users\\Jake_PC\\Documents\\NetBeansProjects\\OJT2\\ServerReceivables\\file.txt");
bos = new BufferedOutputStream(fos);
} catch (FileNotFoundException ex)
{
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0)
{
bos.write(bytes, 0, count);
}
bos.flush();
bos.close();
is.close();
socket.close();
serverSocket.close();
CLIENT
public static void main(String args[])throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(4441);
} catch (IOException ex)
{
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
try
{
socket = serverSocket.accept();
} catch (IOException ex)
{
System.out.println("Can't accept client connection. ");
}
try
{
is = socket.getInputStream();
bufferSize = socket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex)
{
System.out.println("Can't get socket input stream. ");
}
//C:\Users\Jake_PC\Documents\NetBeansProjects\OJT2
try
{
fos = new FileOutputStream("C:\\Users\\Jake_PC\\Documents\\NetBeansProjects\\OJT2\\Client1Receivables\\file.txt");
bos = new BufferedOutputStream(fos);
} catch (FileNotFoundException ex)
{
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0)
{
bos.write(bytes, 0, count);
}
bos.flush();
bos.close();
is.close();
socket.close();
serverSocket.close();
}
private void sendFile(File file)throws IOException
{
Socket socket = null;
String host = "127.0.0.1";
String receiver=txtReceiver.getSelectedItem().toString();
int port=0;
if(receiver=="Client1")
{
port=4441;
}
else if(receiver=="Client2")
{
port=4442;
}
else if(receiver=="Server")
{
port=4440;
}
socket = new Socket(host, port);
//File file = new File("Client.txt");
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
int count;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
}
You need to start a new thread to handle each accepted socket. Examples abound. See for example the Custom Networking trail in the Java Tutorial.
I have implemented a multithreaded client/server program in Java for downloading files, in which the server can concurrently serve the file to many clients by utilizing threads.
When I test the server with a single client it works fine, but when I test with ten or more clients using a shell script then the downloaded files all have different sizes, which differs from the actual size of the file on the server side.
Can anyone explain why this is happening?
Code for Server:
public class FileSend implements Runnable {
Socket sock;
String pathname;
FileSend(Socket s, String filename) {
sock = s;
pathname = System.getenv("HOME") + "/" + Main.spath + "/" + filename;
}
void send(String pathname) throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, ParseException {
try {
byte[] buf = new byte[1024];
OutputStream os = sock.getOutputStream();
//PrintWriter writer = new PrintWriter(os);
BufferedOutputStream out = new BufferedOutputStream(os, 1024);
int i = 0;
File fp = new File(pathname);
RandomAccessFile ra = new RandomAccessFile(fp, "r");
long bytecount = 1024;
////////////////
while ((i = ra.read(buf, 0, 1024)) != -1) {
bytecount += 1024;
out.write(buf, 0, i);
out.flush();
}
sock.shutdownOutput();
out.close();
ra.close();
sock.close();
} catch (IOException ex) {
}
}
public void run() {
try {
try {
try {
try {
send(this.pathname);
} catch (ParseException ex) {
Logger.getLogger(FileSend.class.getName()).log(Level.SEVERE,
null, ex);
}
} catch (NoSuchPaddingException ex) {
Logger.getLogger(FileSend.class.getName()).log(Level.SEVERE,
null, ex);
}
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(FileSend.class.getName()).log(Level.SEVERE, null,
ex);
}
} catch (IOException ex) {
Logger.getLogger(FileSend.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Client Code:
public class FileRecieve implements Runnable {
Socket sock;
String path;
Date T;
//private Date d2;
FileRecieve(Socket s, String fname, Date d1) {
sock = s;
path = Main.Dpath + "/" + fname;
T = d1;
}
public void run() {
try {
byte[] b = new byte[1024];
int len = 0;
long bytcount = 1024;
File fp = new File(path);
// RandomAccessFile ra = new RandomAccessFile(fp,"r");
RandomAccessFile ra = new RandomAccessFile(fp, "rw");
ra.seek(0);
InputStream is = sock.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
while ((len = is.read(b, 0, 1024)) != -1) {
bytcount = bytcount + 1024;
//decrypt
ra.write(b, 0, len);
}
is.close();
ra.close();
sock.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Please help, many thanks in advance.
I have made a similar attempt at a Mutithreaded Client-Server file downloader app. You can check it out at code review. I have used the java.util.concurrent package classes for the multithreading bit.
I am developing one program in which a user can download a number of files. Now first I am sending the list of files to the user. So from the list user selects one file at a time and provides path where to store that file. In turn it also gives the server the path of file where does it exist.
I am following this approach because I want to give stream like experience without file size limitation.
Here is my code..
1) This is server which gets started each time I start my application
public class FileServer extends Thread {
private ServerSocket socket = null;
public FileServer() {
try {
socket = new ServerSocket(Utils.tcp_port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
try {
System.out.println("request received");
new FileThread(socket.accept()).start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
2) This thread runs for each client separately and sends the requested file to the user 8kb data at a time.
public class FileThread extends Thread {
private Socket socket;
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public FileThread(Socket socket) {
this.socket = socket;
System.out.println("server thread" + this.socket.isConnected());
//this.filePath = filePath;
}
#Override
public void run() {
// TODO Auto-generated method stub
try
{
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
try {
//************NOTE
filePath=(String) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = new File(this.filePath);
byte[] buf = new byte[8192];
InputStream is = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(is);
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
int c = 0;
while ((c = bis.read(buf, 0, buf.length)) > 0) {
oos.write(buf, 0, c);
oos.flush();
// buf=new byte[8192];
}
oos.close();
//socket.shutdownOutput();
// client.shutdownOutput();
System.out.println("stop");
// client.shutdownOutput();
ois.close();
// Thread.sleep(500);
is.close();
bis.close();
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
NOTE: here filePath represents the path of the file where it exists on the server. The client who is connecting to the server provides this path. I am managing this through sockets and I am successfully receiving this path.
3) FileReceiverThread is responsible for receiving the data from the server and constructing file from this buffer data.
public class FileReceiveThread extends Thread {
private String fileStorePath;
private String sourceFile;
private Socket socket = null;
public FileReceiveThread(String ip, int port, String fileStorePath,
String sourceFile) {
this.fileStorePath = fileStorePath;
this.sourceFile = sourceFile;
try {
socket = new Socket(ip, port);
System.out.println("receive file thread " + socket.isConnected());
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
oos.writeObject(sourceFile);
oos.flush();
// oos.close();
File f = new File(fileStorePath);
OutputStream os = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buf = new byte[8192];
int c = 0;
//************ NOTE
ObjectInputStream ois = new ObjectInputStream(
socket.getInputStream());
while ((c = ois.read(buf, 0, buf.length)) > 0) {
// ois.read(buf);
bos.write(buf, 0, c);
bos.flush();
// buf = new byte[8192];
}
ois.close();
oos.close();
//
os.close();
bos.close();
socket.close();
//Thread.sleep(500);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
NOTE : Now the problem that I am facing is at the first time when the file is requested the outcome of the program is same as my expectation. I am able to transmit any size of file at first time. Now when the second file is requested (e.g. I have sent file a,b,c,d to the user and user has received file a successfully and now he is requesting file b) the program faces deadlock at this situation. It is waiting for socket's input stream. I put breakpoint and tried to debug it but it is not going in FileThread's run method second time. I could not find out the mistake here. Basically I am making a LAN Messenger which works on LAN. I am using SWT as UI framework.
A more basic problem.
You are only processing the first socket.
while(true) {
new FileThread(socket.accept()).start();
}
As per the suggestion of Peter Lawrey i removed all the redundant streams code from my source code. Now the changed source code is as follows and the problem remains.
1) No change in FileServer. It is as it is .
2) FileThread
public class FileThread extends Thread {
private Socket socket;
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public FileThread(Socket socket) {
this.socket = socket;
System.out.println("server thread" + this.socket.isConnected());
// this.filePath = filePath;
}
#Override
public void run() {
// TODO Auto-generated method stub
try
{
OutputStream oos = socket.getOutputStream();
oos.flush();
InputStream ois = socket.getInputStream();
byte[] buf = new byte[8192];
ois.read(buf);
filePath = new String(buf);
System.out.println(filePath);
File f = new File(this.filePath);
InputStream is = new FileInputStream(f);
int c = 0;
while ((c = is.read(buf, 0, buf.length)) > 0) {
oos.write(buf, 0, c);
oos.flush();
}
oos.close();
System.out.println("stop");
ois.close();
is.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
3) FileReceiverThread
public class FileReceiveThread extends Thread {
private String fileStorePath;
private String sourceFile;
private Socket socket = null;
public FileReceiveThread(String ip, int port, String fileStorePath,
String sourceFile) {
this.fileStorePath = fileStorePath;
this.sourceFile = sourceFile;
try {
socket = new Socket(ip, port);
System.out.println("receive file thread " + socket.isConnected());
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
try {
OutputStream oos = socket.getOutputStream();
oos.write(sourceFile.getBytes());
oos.flush();
File f = new File(fileStorePath);
OutputStream os = new FileOutputStream(f);
byte[] buf = new byte[8192];
int c = 0;
// ************ NOTE
InputStream ois = socket.getInputStream();
while ((c = ois.read(buf, 0, buf.length)) > 0) {
os.write(buf, 0, c);
os.flush();
}
ois.close();
oos.close();
os.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
is there still something which i am missing ?