How to send and receive file with socket programming in java - java

Hello I have a problem with sending and receiving files through sockets in java
I've written 2 while in client and session class one for sending and one for receiving
program starts and send a request file from client to session then session receives it and creates it
after that session send response file to client and client receives it and creates it
when I remove 2nd "while"s in both client and session class , program works and client sends data and session receives it and create the file
but when I add 2nd "while"s again , program stuck and even last operation that I mentioned won't work
Server Class
public class Server {
public Server(int port) {
try {
ServerSocket server = new ServerSocket(port);
while (true) {
Socket client = server.accept();
System.out.println("New client connected" + client.getInetAddress().getHostAddress());
Session clientSocket = new Session(client);
new Thread(clientSocket).start();
}
} catch (IOException i) {
System.out.println(i);
}
}
public static void main(String args[]) {
Server server = new Server(5000);
}}
Session Class :
public class Session implements Runnable{
private Socket socket;
public Session(Socket socket){
this.socket = socket;
}
public void run(){
try {
FileOutputStream fileOutputStream = new FileOutputStream("RequestClient.txt");
FileInputStream fileInputStream = new FileInputStream("Response.txt");
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
int count;
byte[] bytes = new byte[4096];
while ((count = dataInputStream.read(bytes)) > 0) {
fileOutputStream.write(bytes, 0, count);
}
while ((count = fileInputStream.read(bytes)) > 0) {
dataOutputStream.write(bytes, 0, count);
}
fileInputStream.close();
fileOutputStream.close();
dataOutputStream.close();
dataInputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}}
Client Class :
public class Client {
public Client (String address, int port) {
Socket socket = null;
try {
socket = new Socket(address, port);
File requestFile = new File("Request.txt");
FileOutputStream fileOutputStream = new FileOutputStream("ResponseServer.txt");
FileInputStream fileInputStream = new FileInputStream(requestFile);
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
int count;
byte[] buffer = new byte[4096];
while ((count = fileInputStream.read(buffer)) > 0) {
dataOutputStream.write(buffer, 0, count);
}
while ((count = dataInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, count);
}
fileInputStream.close();
fileOutputStream.close();
dataOutputStream.close();
dataInputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
Client connectionService = new Client("127.0.0.1", 5000);
}}

Related

Java socket file transfer - Connection reset

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!

Send files with java socket

i am sending files from two java applications here the source code of the server and the client
public class FileClient {
private Socket s;
public FileClient(String host, int port, String file) {
try {
s = new Socket(host, port);
sendFile(file);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendFile(String file) throws IOException {
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
while ((fis.read(buffer) > 0)) {
dos.write(buffer);
}
fis.close();
dos.close();
}
public static void main(String[] args) {
FileClient fc = new FileClient("192.168.0.167", 1988, "C:/Users/mhattabi/Desktop/fileData.txt");
}
}
and here the source code of the server
public class FileServer extends Thread {
private ServerSocket ss;
public FileServer(int port) {
try {
ss = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Socket clientSock = ss.accept();
saveFile(clientSock);
// ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void saveFile(Socket clientSock) throws IOException {
DataInputStream dis = new DataInputStream(clientSock.getInputStream());
FileOutputStream fos = new FileOutputStream("fileData.txt");
byte[] buffer = new byte[4096];
int filesize = 15123; // Send file size in separate msg
int read = 0;
int totalRead = 0;
int remaining = filesize;
while((read = dis.read(buffer)) > 0) {
totalRead += read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
fos.close();
dis.close();
}
public static void main(String[] args) {
FileServer fs = new FileServer(1988);
fs.start();
}
}
the problem that in the server i received the file but there is extra character in it look like this.Any help will be appreciated thanks
Usual problem.
while ((fis.read(buffer) > 0)) {
dos.write(buffer);
}
You're ignoring the count returned by the read, and assuming that it filled the buffer. It should be:
while ((count = fis.read(buffer) > 0)) {
dos.write(buffer, 0, count);
}
Curiously enough you have this right in the server. NB You don't need a DataOutputStream here.
byte[] buffer = new byte[4096];
I think the" extra character" come from this place;every time you write 4096 byte
,at last time it happened less than 4096 byte.and then you get extra character

Multiple file chunks transfer over socket to multiple clients

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();
}
}

Websocket server to initialise a connection to another websocket server

Is there a way to get a websocket server to connect to another websocket server? I wrote this snippet in Java but it doesn't work. I don't get any errors or exceptions, it just waits forever to connect.
#OnMessage
public void message(Session session, String msg){
String URL = "ws://wildfly2-ciri.rhcloud.com:8000/echo";
try {
System.out.println("**1 Got new message: " + msg);
String forward = "This is WildFly 1: " + msg;
System.out.println("**1 Init new session");
Session newSession = session.getContainer().connectToServer(Client.class, URI.create(URL));
System.out.println("**1 Sending to wildfly2");
newSession.getBasicRemote().sendText(forward);
} catch (Exception e) {
e.printStackTrace();
}
}
Basically, I want this server to initialize a new websocket connection to another server at another address. However, the program stops when it tries to make a new connection. Is there a flaw in my thinking or is this kind of connection impossible?
You may find this useful. This is one of my older socket programs which I used to communicate between client and server. I have attached both of client and code for the program which would send XML files. You will however, need to edit a few things in order to get her workin' for you. Play this with file and get a feel for sockets and apply it to your program. Happy Learnings my friend!
public static void main(String[] args) throws IOException {
Socket socket = null;
String host = "127.0.0.1";
socket = new Socket(host, 4444);
File file = new File("C:\\testXML.xml");
// 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 class Server {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} 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:\\xxxXXXXxxx.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();
}
}

Synchronize server with client java sockets

Currently I am working on a server/client application which sends data using java with Runnable and threads. The problem is that the client is sending the data and when the server starts to read it the client has already finished and closed the connection which on the server side only a partially of the data is arrived, can they be setup to be synchronized?
this is the client:
private void ConnectionToServer(final String ipAddress, final int Port) {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
socket = new Socket(ipAddress, Port);
bos = new BufferedOutputStream(socket.getOutputStream());
dos = new DataOutputStream(socket.getOutputStream());
File f = new File("C:/Users/lukeLaptop/Downloads/RemoveWAT22.zip");
String data = f.getName()+f.length();
byte[] b = data.getBytes();
sendBytes(b, 0, b.length);
dos.flush();
bos.flush();
bis.close();
dos.close();
//clientProcessingPool.submit(new ServerTask(socket));
} catch (IOException ex) {
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); } finally {
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
public void sendBytes(byte[] myByteArray, int start, int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("Negative length not allowed");
}
if (start < 0 || start >= myByteArray.length) {
throw new IndexOutOfBoundsException("Out of bounds: " + start);
}
// Other checks if needed.
// May be better to save the streams in the support class;
// just like the socket variable.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(len);
if (len > 0) {
dos.write(myByteArray, start, len);
}
}
server code:
private void acceptConnection() {
try {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(8080);
while (true) {
socket = server.accept();
System.out.println("Got a client !");
bis = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(socket.getInputStream());
String data = readBytes().toString();
System.out.println(data);
bos.close();
dis.close();
//clientProcessingPool.submit(new ClientTask(socket));
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
} catch (Exception io) {
io.printStackTrace();
}
}
public byte[] readBytes() throws IOException {
// Again, probably better to store these objects references in the support class
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
int len = dis.readInt();
byte[] data = new byte[len];
if (len > 0) {
dis.readFully(data);
}
return data;
}
You mixed up many things:
Variables start most of the time with a lowercase letter, e.g. int port, int ipAddress
Classes start with a uppercase letter, e.g. Client, Server
only open one Data*stream on a socket. new DataInputStream(socket.getInputStream()) or new BufferedInputStream(socket.getInputStream()), but not both
If you need both, chain them: new DataInputStream(new BufferedInputStream(socket.getInputStream()));
KISS (Keep it short & simple)
If you use a DataInputStream, then use the given functionality of sending objects and primitives, e.g. sendUTF(), sendInt(), sendShort(), and so on...
Name your vars right: servertask is a client thread? no
Move long anonymous classes to a new class
Don't use port 8080, this port is used for many other application and will cause problems
example code regarding your example an my advices:
Server
public class Server implements Runnable {
private void acceptConnection() {
Thread serverThread = new Thread(this);
serverThread.start();
}
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(8081);
while (true) {
Socket socket = server.accept();
System.out.println("Got a client !");
// either open the datainputstream directly
DataInputStream dis = new DataInputStream(socket.getInputStream());
// or chain them, but do not open two different streams:
// DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
// Your DataStream allows you to read/write objects, use it!
String data = dis.readUTF();
System.out.println(data);
dis.close();
// in case you have a bufferedInputStream inside of Datainputstream:
// you do not have to close the bufferedstream
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server().acceptConnection();
}
}
description:
main: create a new Server Object, which is a Runnable
acceptConnections: create a Thread
run:
open a Serversocket
wait for a connection
open exactly one stream
read the Data
close the stream and wait for next connection
Client
public class Client {
private static void sendToServer(String ipAddress, int port) throws UnknownHostException, IOException {
Socket socket = new Socket(ipAddress, port);
// same here, only open one stream
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
File f = new File("C:/Users/lukeLaptop/Downloads/RemoveWAT22.zip");
String data = f.getName()+f.length();
dos.writeUTF(data);
dos.flush();
dos.close();
}
public static void main(String[] args) throws UnknownHostException, IOException {
Client.sendToServer("localhost", 8081);
}
}
description (This one is straight forward):
open socket
open DataStream
send Data
flush and close

Categories