I've been having some trouble trying to send a file from a server to a client. I can't seem to send the same file from the server to the client into two SEPERATE files. Instead, it just appends to the end of the first file! Any help would be appreciated.
EDIT : I've modified the code. I've modularized the file sending and recieving tasks into 2 functions 'sendfile' and 'recievefile'. The error I'm getting now is that the socket is closed at the sendfile and recievefile functions after the second call. But all I'm closing is the file and the output and input streams! Perhaps closing those streams will close the socket too...? Anyways, I've tried NOT closing the input and output streams and what happens is - 1)nothing gets transferred to the destination file. So I just get a blankly created file at the server end. 2)The second file doesn't even get created. Great.
Any help would, as usual, be appreciated.
Server:
package com.http.server;
import java.io.*;
import java.net.*;
public class Server
{
public static void main(String args[])throws Exception
{
System.out.println("Server running...");
/* Listen on port 5555 */
ServerSocket server = new ServerSocket(5555);
/* Accept the sk */
Socket sk = server.accept();
System.out.println("Server accepted client");
BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream()));
BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
/* Read the filename */
String serverlocation = "C:/Users/Arjun/Desktop/CNW model/HTTP Website/";
String filename = serverlocation + inReader.readLine();
if ( !filename.equals("") ){
/* Reply back to client with READY status */
outReader.write("READY\n");
outReader.flush();
}
sendfile(sk, filename);
sendfile(sk, filename);
outReader.close();
inReader.close();
sk.close();
server.close();
}
public static void sendfile(Socket sk, String filename)
{
try{
OutputStream output = sk.getOutputStream();
FileInputStream file = new FileInputStream(filename);
byte[] buffer = new byte[sk.getSendBufferSize()];
int bytesRead = 0;
while((bytesRead = file.read(buffer))>0)
{
output.write(buffer,0,bytesRead);
}
file.close();
output.close();
}
catch (Exception ex){
System.out.println(ex);
}
}
}
Client:
package com.http.client;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Client extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextField txtFile;
public static void main(String args[]){
/* Create and display the client form */
Client clientForm = new Client();
clientForm.Display();
}
public void Display(){
JFrame frame = new JFrame();
frame.setTitle("Client");
FlowLayout layout = new FlowLayout();
layout.setAlignment(FlowLayout.LEFT);
JLabel lblFile = new JLabel("URL:");
txtFile = new JTextField();
txtFile.setPreferredSize(new Dimension(150,30));
JButton btnTransfer = new JButton("Get");
btnTransfer.addActionListener(this);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(layout);
mainPanel.add(lblFile);
mainPanel.add(txtFile);
mainPanel.add(btnTransfer);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
/* File Open Dialog box allows the user to select a file */
String filename=txtFile.getText();
try{
/* Try to connect to the server on localhost, port 5555 */
Socket sk = new Socket("localhost", 5555);
/* Send filename to server */
OutputStreamWriter outreader = new OutputStreamWriter(sk.getOutputStream());
outreader.write(filename + "\n");
outreader.flush();
/* Get response from server */
BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream()));
String serverStatus = inReader.readLine(); // Read the first line
/* If server is ready, receive the file */
while ( !serverStatus.equals("READY") ){}
/* Create a new file in the tmp directory using the filename */
recievefile(sk,filename);
recievefile(sk,"xx"+filename);
JOptionPane.showMessageDialog(this, "Transfer complete");
inReader.close();
outreader.close();
sk.close();
}
catch (Exception ex){
/* Catch any errors */
JOptionPane.showMessageDialog(this, ex.getMessage());
System.out.println(ex);
}
}
public void recievefile(Socket sk, String filename)
{
try{
InputStream input = sk.getInputStream();
FileOutputStream wr = new FileOutputStream(new File("C:/tmp/" + new File(filename).getName()));
byte[] buffer = new byte[sk.getReceiveBufferSize()];
int bytesReceived = 0;
while((bytesReceived = input.read(buffer))>0)
{
/* Write to the file */
wr.write(buffer,0,bytesReceived);
}
wr.close();
input.close();
}
catch (Exception ex){
/* Catch any errors */
JOptionPane.showMessageDialog(this, ex.getMessage());
System.out.println(ex);
}
}
}
When you send the files, you are just appending one to the end of the other so thats how the client see them.
You need to let the client know when to stop reading one file and start reading the second.
The simplest approach is to send the length of the file before the file and only read exactly than amount of data.
BTW: You cannot combine binary and text streams the way you have. This is more likely to lead to confusion. In your case you need to send binary so make everything binary with DataInputStream and DataOutputStream.
What I had in mind is something like.
public static void sendFile(DataOutput out, String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
byte[] bytes = new byte[8192];
try {
long size = fis.getChannel().size();
out.writeLong(size);
for (int len; (len = fis.read(bytes, 0, (int) Math.min(bytes.length, size))) > 0; ) {
out.write(bytes, 0, len);
size -= len;
}
assert size == 0;
} finally {
fis.close();
}
}
public void receiveFile(DataInput in, String filename) throws IOException {
long size = in.readLong();
FileOutputStream fos = new FileOutputStream(filename);
byte[] bytes = new byte[8192];
try {
for (int len; (len = (int) Math.min(size, bytes.length)) > 0; ) {
in.readFully(bytes, 0, len);
fos.write(bytes, 0, len);
size -= len;
}
} finally {
fos.close();
}
}
Related
I'm trying to make a program that transfer a file using java sockets. This is what I've written so far:
Sender:
private ServerSocket sendSocket;
public Send(int port) throws IOException
{
sendSocket = new ServerSocket(port);
}
public void run()
{
Socket socket = null;
try
{
Scanner scan = new Scanner(System.in);
InputStream inStream = null;
socket = sendSocket.accept();
inStream = socket.getInputStream();
String filePath = scan.nextLine();
OutputStream thisFile = new FileOutputStream(filePath);
byte[] bytes = new byte[16*1024];
int count;
while ((count = inStream.read(bytes)) > 0)
{
thisFile.write(bytes, 0, count);
}
System.out.println("Done!");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Receiver:
private static OutputStream thatFile;
public Receive(Socket socket) throws IOException
{
thatFile = socket.getOutputStream();
}
public void run()
{
try
{
System.out.println("Where do you want to save the file?");
Scanner scan = new Scanner(System.in);
String filePath = scan.nextLine();
File saveFile = new File(filePath);
byte[] bytes = new byte[16 * 1024];
InputStream inStream = new FileInputStream(saveFile);
int count;
while ((count = inStream.read(bytes)) > 0)
{
thatFile.write(bytes, 0, count);
}
}
catch (Exception e)
{
}
}
}
But whenever I run the program, after the client gives a destination for the download path, connection reset error happens on the sender side. I'm sure the port is open as I've tested on this port before. What's the problem?
This is what happens when I run the program:
Sender side:
Press 1 to send or 2 to receive.
1
What is the file's path?
C:\Users\orie5\Documents\Cmp\a.txt
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:323)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)
at java.base/java.io.InputStream.read(InputStream.java:218)
at def.Send.run(Send.java:47)
Receiver Side:
Press 1 to send or 2 to receive.
2
Please enter the ip of the peer you want to connect to.
Where do you want to save the file?
C:\Users\orie5\Documents\Cmp\b.txt
Thanks in advance!
hi guys i tried to send txt through socket it worked using the following source code but i got an exception when i want to send the zip files.Any help will be appreciated thanks
Java server
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub}
sendFile("FileTest.rar");
}
public static Boolean sendFile(String strFileToSend) {
try {
ServerSocket serverSocket = new ServerSocket(1592);
Socket socket = serverSocket.accept();
System.out.println("Connection accepted from " + socket);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
File file = new File(strFileToSend);
// send file length
out.println(file.length());
// read file to buffer
byte[] buffer = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.read(buffer, 0, buffer.length);
// send file
BufferedOutputStream bos = new BufferedOutputStream(
socket.getOutputStream());
bos.write(buffer);
bos.flush();
// added
dis.close();
serverSocket.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
C# client
public static bool receiveFile(string ip,string strFilePath)
{
try
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(ip, 1592);
NetworkStream networkStream = tcpClient.GetStream();
StreamReader sr = new StreamReader(networkStream);
//read file length
int length = int.Parse(sr.ReadLine());
//read bytes to buffer
byte[] buffer = new byte[length];
networkStream.Read(buffer, 0, (int)length);
//write to file
BinaryWriter bWrite = new BinaryWriter(File.Open(strFilePath, FileMode.Create));
bWrite.Write(buffer);
bWrite.Flush();
bWrite.Close();
return true;
}
catch(Exception exException)
{
MessageBox.Show(exException.Message);
return false;
}
}
The problem is when i want to deal with rar or zip files.
Thanks in advance
i got the exeption below.It occurs at this line in the client app
int length = int.Parse(sr.ReadLine());
This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 4 years ago.
Is there any way to copy file to remote linux machine from windows using java without FTP protocol?
Transfer file using java socket
Server/Sender
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Sender {
public static Scanner scanner;
/**
*
* #param args
* this function collect all required data from user.
* #throws IOException
*/
public static void main(String[] args) throws IOException
{
String fileLocation;
int portNo;
scanner=new Scanner(System.in);
System.out.println("Enter port number of machine(e.g. '2000') :");
portNo=scanner.nextInt();
System.out.println("Please enter file location with file name (e.g. 'D:\\abc.txt'): ");
fileLocation=scanner.next();
Sender.send(portNo,fileLocation);
}
/**
* this function actually transfers file
* #param portNo
* #param fileLocation
* #return
* #throws IOException
*/
public static void send(int portNo,String fileLocation) throws IOException
{
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
OutputStream outputStream = null;
ServerSocket serverSocket = null;
Socket socket = null;
//creating connection between sender and receiver
try {
serverSocket = new ServerSocket(portNo);
System.out.println("Waiting for receiver...");
try {
socket = serverSocket.accept();
System.out.println("Accepted connection : " + socket);
//connection established successfully
//creating object to send file
File file = new File (fileLocation);
byte [] byteArray = new byte [(int)file.length()];
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(byteArray,0,byteArray.length); // copied file into byteArray
//sending file through socket
outputStream = socket.getOutputStream();
System.out.println("Sending " + fileLocation + "( size: " + byteArray.length + " bytes)");
outputStream.write(byteArray,0,byteArray.length); //copying byteArray to socket
outputStream.flush(); //flushing socket
System.out.println("Done."); //file has been sent
}
finally {
if (bufferedInputStream != null) bufferedInputStream.close();
if (outputStream != null) bufferedInputStream.close();
if (socket!=null) socket.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
if (serverSocket != null) serverSocket.close();
}
}
}
Client/Receiver
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Scanner;
public class Receiver {
public static Scanner scanner;
public static void main (String [] args ) throws IOException {
String fileLocation,ipAddress;
int portNo;
scanner=new Scanner(System.in);
System.out.println("Enter ipAddress of machine(if you are testing this on same machine than enter 127.0.0.1) :");
ipAddress=scanner.next();
System.out.println("Enter port number of machine(e.g. '2000') :");
portNo=scanner.nextInt();
System.out.println("Please enter file location with file name to save (e.g. 'D:\\abc.txt'): "); //you can modify this program to receive file name from server and then you can skip this step
fileLocation=scanner.next();
Receiver.receiveFile(ipAddress, portNo, fileLocation);
}
public static void receiveFile(String ipAddress,int portNo,String fileLocation) throws IOException
{
int bytesRead=0;
int current = 0;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
Socket socket = null;
try {
//creating connection.
socket = new Socket(ipAddress,portNo);
System.out.println("connected.");
// receive file
byte [] byteArray = new byte [6022386]; //I have hard coded size of byteArray, you can send file size from socket before creating this.
System.out.println("Please wait downloading file");
//reading file from socket
InputStream inputStream = socket.getInputStream();
fileOutputStream = new FileOutputStream(fileLocation);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bytesRead = inputStream.read(byteArray,0,byteArray.length); //copying file from socket to byteArray
current = bytesRead;
do {
bytesRead =inputStream.read(byteArray, current, (byteArray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bufferedOutputStream.write(byteArray, 0 , current); //writing byteArray to file
bufferedOutputStream.flush(); //flushing buffers
System.out.println("File " + fileLocation + " downloaded ( size: " + current + " bytes read)");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
if (fileOutputStream != null) fileOutputStream.close();
if (bufferedOutputStream != null) bufferedOutputStream.close();
if (socket != null) socket.close();
}
}
}
I have to transfer chunks of a file to different clients using one server.
When i run the server file and provide the name of the file it successfully makes chunks. when i run the first client for first time it works but when i run it for the client again(by that i mean when i connect as a second client) it fails to transfer chunks to the second client. Complete code of server and client are shown below.
error is for the second client it starts reading the contents of the file as filename and program terminates.
provide a large text file(1MB) file as input to server
Server Code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class server {
private static final int sPort = 8000; //The server will be listening on this port number
public static String str;
public static int c;
public static void main(String[] args) throws Exception {
System.out.println("The server is running.");
ServerSocket listener = new ServerSocket(sPort);
int clientNum = 1;
System.out.println("Enter the name of the file: ");
Scanner in = new Scanner(System.in);
str = in.nextLine();
String path = System.getProperty("user.dir");
String filepath = path +"/"+ str;
in.close();
try {
c=splitFile(new File(filepath));
} catch (IOException e1) {
e1.printStackTrace();
}
try {
while(true) {
new Handler(listener.accept(),clientNum,c).start();
System.out.println("Client " + clientNum + " is connected!");
clientNum++;
}
} finally {
listener.close();
}
}
/**
* A handler thread class. Handlers are spawned from the listening
* loop and are responsible for dealing with a single client's requests.
*/
private static class Handler extends Thread {
private Socket connection;
private int chunkcount;
private ObjectInputStream in; //stream read from the socket
private ObjectOutputStream out; //stream write to the socket
private int no; //The index number of the client
public Handler(Socket connection, int no,int c) {
this.connection = connection;
this.no = no;
this.chunkcount=c;
}
public void run() {
try{
//initialize Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
try{
String path = System.getProperty("user.dir");
path=path+"/"+"chunks"+ "/";
System.out.println(path);
System.out.println("Total chunks: "+chunkcount);
int i=no;
int j=i;
int k=0;
OutputStream op=connection.getOutputStream();
DataOutputStream d = new DataOutputStream(op);
d.writeInt(no);
d.flush();
System.out.println("value of j or clientnum: "+j);
while(j<chunkcount)
{
k++;
j=j+5;
}
System.out.println(k);
d.writeInt(k);
d.flush();
//d.close();
while(i<chunkcount)
{
String pathname= path+Integer.toString(i)+str;
System.out.println(i+str);
sendFile(connection,pathname);
i=i+5;
}
}
catch(Exception e){
e.printStackTrace();
}
}
catch(IOException ioException){
System.out.println("Disconnect with Client " + no);
}
finally{
//Close connections
try{
in.close();
out.close();
connection.close();
}
catch(IOException ioException){
System.out.println("Disconnect with Client " + no);
}
}
}
}
public static int splitFile(File f) throws IOException {
int partCounter = 1;//I like to name parts from 001, 002, 003, ...
//you can change it to 0 if you want 000, 001, ...
int sizeOfFiles = 102400;// 1MB
byte[] buffer = new byte[sizeOfFiles];
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(f))) {//try-with-resources to ensure closing stream
String name = f.getName();
String path = f.getParent();
long sizefile = f.getTotalSpace();
String newpath = path + "/" + "chunks";
File dir = new File(newpath);
dir.mkdir();
int tmp = 0;
while ((tmp = bis.read(buffer)) > 0) {
//write each chunk of data into separate file with different number in name
File newFile = new File(dir, String.format("%d", partCounter++) + name );
//System.out.println(f.getParent());
try (FileOutputStream out = new FileOutputStream(newFile)) {
out.write(buffer, 0, tmp);//tmp is chunk size
}
}
System.out.println("File details are : "+name+" "+sizefile);
System.out.println("Number of chunks: "+ (partCounter-1));
}
return (partCounter-1);
}
public static void sendFile(Socket conn,String fileName) throws IOException
{
File myFile = new File(fileName);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
dis.close();
}
}
client code:
import java.net.*;
import java.io.*;
public class Client {
Socket requestSocket; //socket connect to the server
ObjectOutputStream out; //stream write to the socket
ObjectInputStream in; //stream read from the socket
public Client() {}
void run()
{
try{
//create a socket to connect to the server
requestSocket = new Socket("localhost", 8000);
System.out.println("Connected to localhost in port 8000");
//initialize inputStream and outputStream
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
in = new ObjectInputStream(requestSocket.getInputStream());
System.out.println("Ready to receive files ( Enter QUIT to end):");
BufferedInputStream in1 = new BufferedInputStream(requestSocket.getInputStream());
DataInputStream d = new DataInputStream(in1);
int clientnum=d.readInt();
String path = System.getProperty("user.dir");
String oppath = path + "/" + "Client" + clientnum;
File dir = new File(oppath);
dir.mkdir();
int numchunk=d.readInt();
System.out.println(numchunk);
int jakarta=1;
while(jakarta<=numchunk ){
jakarta++;
String newpath=oppath+"/";
File f = new File(newpath);
f.createNewFile();
receiveFile(requestSocket,newpath);
System.out.println("File Received");
}
}
catch (ConnectException e) {
System.err.println("Connection refused. You need to initiate a server first.");
}
catch(UnknownHostException unknownHost){
System.err.println("You are trying to connect to an unknown host!");
}
catch(IOException ioException){
ioException.printStackTrace();
}
finally{
//Close connections
try{
in.close();
out.close();
requestSocket.close();
}
catch(IOException ioException){
ioException.printStackTrace();
}
}
}
//send a message to the output stream
public static void receiveFile(Socket s1,String oppath) throws IOException
{
String fileName;
try {
int bytesRead;
InputStream in = s1.getInputStream();
DataInputStream clientData = new DataInputStream(in);
fileName = clientData.readUTF();
OutputStream output = new FileOutputStream(oppath+fileName);
long size = clientData.readLong();
byte[] buffer = new byte[1024];
while (size > 0
&& (bytesRead = clientData.read(buffer, 0,
(int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.flush();
output.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//main method
public static void main(String args[])
{
Client client = new Client();
client.run();
}
}
I send a wave file using a client and server method.
How could I play this file on the client once it's received?
This is the server code used to send the wave file:
import java.lang.*;
import java.io.*;
import java.net.*;
class Server {
//D:\Documents and Settings\Desktop\gradpro\test1
static final String OUTPUTFILENAME = "C:\\Documents and Settings\\Administratore\\Desktop\\gradpro\\test1\\s1.wav";
static final int PORT = 8811;
public static void main(String args[]) {
System.out.println("New server running...\n\n");
// Infinite loop, innit
while ( true ) {
try {
//Create a socket
ServerSocket srvr = new ServerSocket(PORT);
Socket skt = srvr.accept();
//Create a file output stream, and a buffered input stream
FileOutputStream fos = new FileOutputStream(OUTPUTFILENAME);
BufferedOutputStream out = new BufferedOutputStream(fos);
BufferedInputStream in = new BufferedInputStream( skt.getInputStream() );
//Read, and write the file to the socket
int i;
while ((i = in.read()) != -1) {
out.write(i);
//System.out.println(i);
System.out.println("Receiving data...");
}
out.flush();
in.close();
out.close();
skt.close();
srvr.close();
System.out.println("Transfer complete.");
}
catch(Exception e) {
System.out.print("Error! It didn't work! " + e + "\n");
}
//Sleep...
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.err.println("Interrupted");
}
} //end infinite while loop
}
}
Look at the javax.sound.sampled API.
You can use the AudioClip class to play WAV files; alternatively, you can use the Java Sound API.