Sending much files through socket Java c# - java

I am trying to send set of files through socket C# and Java application, I am not able to recieve all files. The server application closes connections, I think, because the server always closes connection after sending the file without making sure that the client app received the file.
Here is the C# client code:
public static void connectWithRemoteServer(string strIp, string strMessage, out
string strResult)
{
strResult = "";
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(strIp, 1593);
NetworkStream networkStream = tcpClient.GetStream();
StreamReader sr = new StreamReader(networkStream);
if (strMessage.Substring(0,1).Equals("s"))
{
byte[] byteBuffer = Encoding.ASCII.GetBytes(strMessage);
networkStream.Write(byteBuffer, 0, byteBuffer.Length);
strResult = sr.ReadLine();
}
else if (strMessage.Substring(0, 1).Equals("f"))
{
byte[] byteBuffer = Encoding.ASCII.GetBytes(strMessage);
networkStream.Write(byteBuffer, 0, byteBuffer.Length);
int length = int.Parse(sr.ReadLine());
byte[] buffer = new byte[length];
networkStream.Read(buffer, 0, (int)length);
string var = strMessage.Substring(1);
//write to file
BinaryWriter bWrite = new BinaryWriter(File.Open(var, FileMode.Create));
bWrite.Write(buffer);
bWrite.Flush();
bWrite.Close();
strResult = "ok";
}
tcpClient.Close();
}
}
foreach (string strFilePath in lst)
{
Utilities.connectWithRemoteServer("192.168.0.167", "f" + strFilePath, out str);
}
Java Server app
while(true)
{
String listeFiles = "";
ServerSocket serverSocket = new ServerSocket(1593);
System.out.println("Server started and waiting for request..");
Socket socket = serverSocket.accept();
System.out.println("Connection accepted from " + socket);
// this is to send to the client application
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// this is to receive from the client application
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
byte[] bytearray = new byte[in.available()];// recived byte from the
// client application
in.read(bytearray, 0, bytearray.length);// read recieved byte from
String strRecieved = new String(bytearray);// get the received string
System.out.println(strRecieved);
//strRecieved = strRecieved.trim();
if(strRecieved.substring(0,1).equals("s"))
{
List<String> lstFiles = GetFiles.getListFilesPath("./testData");
for (String str : lstFiles) {
listeFiles = str + "+" + listeFiles;
}
String listFilesToSend = listeFiles.substring(0, listeFiles.length() - 1);
out.println(listFilesToSend);
System.out.println("List Files Send ");
serverSocket.close();
socket.close();
}
else if (strRecieved.substring(0,1).equals("f"))
{
File file = new File(strRecieved.substring(1));
// // 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();
serverSocket.close();
socket.close();
}
}
}
How to make sure the file has been received successfully before send the next file Issue
unable to write data to the transport connection an existing connection was forcibly closed
Any help would be appreciated.
Thank you .

Related

Sending some lines of string to server (UDP) in java

I try to send a string consist of some lines in one datagram packet from my client to server ,my problem is when I send the string only first line will send to the server ,I want to send one line then after 10 second send another line and another, how can I solve it???
this is my client code for sending string :
String msge="null";
String atCurrentLine = null;
try (BufferedReader cl = new BufferedReader(
new FileReader("Client1.txt"))) {
while ((atCurrentLine = cl.readLine()) != null) {
msge=atCurrentLine;
System.out.println(msge);
}
} catch (IOException e) {
e.printStackTrace();
}
DatagramSocket skt = null;
try {
skt = new DatagramSocket();
byte[] b = msge.getBytes();
InetAddress host = InetAddress.getByName("localhost");
int cl = 6700;
DatagramPacket request = new DatagramPacket(b,b.length,host,cl);
skt.send(request);
and this code for server to receive:
DatagramSocket skt = null;
try {
skt = new DatagramSocket(6700);
byte [] buffer = new byte[1000];
while (true) {
DatagramPacket request = new DatagramPacket(buffer,buffer.length);
skt.receive(request);
String [] arrayMsg = (new String(request.getData())).split(" ");
sms=arrayMsg[0];
System.out.println("received from client :"+arrayMsg[0]);

Send request line + File using Sockets - java

I am trying to send a "request line" and a file through a socket.
Client (sender)
Socket socket = new Socket(hostName, SOCKET_PORT);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
FileInputStream fis = new FileInputStream(fileName);
os.writeBytes("PUT c:\dev\foo\helloworld.txt" + "\r\n")
byte[] buffer = new byte[1024];
int bytes;
while((bytes = fis.read(buffer)) != -1 ) {
try {
os.write(buffer, 0, bytes);
} catch (IOException e) {e.printStackTrace();}
}
Sever (receiver)
ServerSocket serverSocket = new ServerSocket(SOCKET_PORT);
Socket clientSoc = serverSocket.accept();
InputStream inputStream = clientSoc.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String requestLine = bufferedReader.readLine();
File currentFile = (File)new ObjectInputStream(inputStream).readObject(); //This doesn't work
byteSequence = new byte[new Long(currentFile.length()).intValue()];
for(int i =0; i<currentFile.length();i++){
byteSequence[i] = (byte)clientSoc.getInputStream().read();
}
try {
FileOutputStream newFile = new FileOutputStream(currentFile.getName());
newFile.write(byteSequence,0, byteSequence.length);
} catch (IOException e) {e.printStackTrace();}
I am able to read the request line on the server but when I attempt to read the file it throws an exception (line below).
File currentFile = (File)new ObjectInputStream(inputStream).readObject();
java.io.Stream.CorruptedException:
java.io.StreamCorruptedException: invalid stream header: 0A48656C
What exactly am I doing wrong?
You are trying to access an object that was not even passed to the socket.. you only passed a byte of string to the server but you never pass an Object to the server using the ObjectOutputStream..

Resume file upload/download after lost connection (Socket programming)

I'm writing a program to download/upload a file between a client and server using socket programming. The code i've written till now works in the sense that i can sucesfully transfer files. However , if a connection fails due to problem in the network/client/server while a download / upload is occuring.. i need to RESUME the download/upload from the original point(Do not want the originally sent data to be resent). I'm not sure how to go about this. I'm reading the file into a byte array and sending it across the network. My initial idea is that everytime i'm downloading.. i should check if the file already exists and read the data into a byte array --> send the data to the server for comparison and then return the remaining data from the server file by comparing the two byte arrays. But this seems inefficient and takes away the point of resuming a download(since i'm sending the data again).
Note: The file name is an unique identifier.
I would really appreciate it if anybody could give me suggestions as to how i should implement the file resume functionality?
Server side code:
package servers;
import java.io.*;
import java.net.*;
import java.util.Arrays;
public class tcpserver1 extends Thread
{
public static void main(String args[]) throws Exception
{
ServerSocket welcomeSocket = null;
try
{
welcomeSocket = new ServerSocket(5555);
while(true)
{
Socket socketConnection = welcomeSocket.accept();
System.out.println("Server passing off to thread");
tcprunnable tcprunthread = new tcprunnable(socketConnection);
Thread thrd = new Thread(tcprunthread);
thrd.start();
System.out.println(thrd.getName());
}
}
catch(IOException e){
welcomeSocket.close();
System.out.println("Could not connect...");
}
}
}
class tcprunnable implements Runnable
{
Socket socke;
public tcprunnable(Socket sc){
socke = sc;
}
public void download_server(String file_name)
{
System.out.println("Inside server download method");
try
{
System.out.println("Socket port:" + socke.getPort());
//System.out.println("Inside download method of thread:clientsentence is:"+clientSentence);
// Create & attach output stream to new socket
OutputStream outToClient = socke.getOutputStream();
// The file name needs to come from the client which will be put in here below
File myfile = new File("D:\\ "+file_name);
byte[] mybytearray = new byte[(int) myfile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0, mybytearray.length);
System.out.println("Arrays on server:"+Arrays.toString(mybytearray));
outToClient.flush();
bis.close();
}
catch(FileNotFoundException f){f.printStackTrace();}
catch(IOException ie){
ie.printStackTrace();
}
}
public void upload_server(String file_name){
try{
byte[] mybytearray = new byte[1024];
InputStream is = socke.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream("D:\\ "+file_name);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
do {
baos.write(mybytearray);
bytesRead = is.read(mybytearray);
}
while (bytesRead != -1);
bos.write(baos.toByteArray());
System.out.println("Array on server while downloading:"+Arrays.toString(baos.toByteArray()));
bos.close();
}
catch(FileNotFoundException fe){fe.printStackTrace();}
catch(IOException ie){ie.printStackTrace();}
}
#Override
public void run()
{
try
{
System.out.println("Server1 up and running" + socke.getPort());
// Create & attach input stream to new socket
BufferedReader inFromClient = new BufferedReader
(new InputStreamReader(socke.getInputStream()));
// Read from socket
String clientSentence = inFromClient.readLine();
String file_name = inFromClient.readLine();
System.out.println("Sever side filename:" + file_name);
try{
if(clientSentence.equals("download"))
{
download_server(file_name);
}
else if(clientSentence.equals("upload"))
{
upload_server(file_name);
System.out.println("Sever side filename:" + file_name);
}
else
{
System.out.println("Invalid input");
}
}
catch(NullPointerException npe){
System.out.println("Invalid input!");
}
socke.close();
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("Exception caught");
}
}
}
Client side code:
package clients;
import java.io.*;
import java.net.*;
import java.util.Arrays;
public class tcpclient1
{
public static void main (String args[]) throws Exception
{
// Create input stream to send sentence to server
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = null;
while(true){
System.out.println("Please enter the server you want to use");
System.out.println("Enter 1 for Server 1 and 2 for Server2");
String server_choice = inFromUser.readLine();
if(server_choice.equals("1")){
// Create client socket to connect to server
// The server to use will be specified by the user
clientSocket = new Socket("localhost",5555);
break;
}
else if(server_choice.equals("2"))
{
clientSocket = new Socket("localhost",5556);
break;
}
else
{
System.out.println("Invalid entry");
}
}
System.out.println("Please enter download for dowloading");
System.out.println("Please enter upload for uploading");
// sentence is what'll be received from input jsp
String sentence = inFromUser.readLine();
if(sentence.equals("download"))
{
download_client(clientSocket,sentence);
}
else if(sentence.equals("upload"))
{
upload_client(clientSocket,sentence);
}
else
{
System.out.println("Invalid input");
}
clientSocket.close();
}
public static void download_client(Socket clientSocket , String sentence)
{
try{
// Create output stream attached to socket
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
// Send line to server
outToServer.writeBytes(sentence+'\n');
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the name of file to download:");
String file_to_download = inFromUser.readLine();
if(searching(file_to_download))
{
// Read local file and send that to the server for comparison
// DONT THINK THIS IS THE RIGHT WAY TO GO ABOUT THINGS SINCE IT BEATS THE PURPOSE OF RESUMING A DOWNLOAD/UPLOAD
}
// Send filetodownload to server
outToServer.writeBytes(file_to_download+'\n');
byte[] mybytearray = new byte[1024];
InputStream is = clientSocket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream("E:\\ "+file_to_download);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
do {
baos.write(mybytearray);
bytesRead = is.read(mybytearray);
}
while (bytesRead != -1);
bos.write(baos.toByteArray());
System.out.println("Array on client while downloading:"+Arrays.toString(baos.toByteArray()));
bos.close();
}
catch(FileNotFoundException fe){fe.printStackTrace();}
catch(IOException ie){ie.printStackTrace();}
}
public static void upload_client(Socket clientSocket, String sentence)
{
try{
// Create output stream attached to socket
DataOutputStream outToServer1 = new DataOutputStream(clientSocket.getOutputStream());
// Send line to server
outToServer1.writeBytes(sentence+'\n');
System.out.println("In the client upload method");
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the name of file to upload:");
String file_to_upload = inFromUser.readLine();
//System.out.println("Cline side file name:"+file_to_upload);
outToServer1.writeBytes(file_to_upload+'\n');
System.out.println(file_to_upload);
OutputStream outtoserver = clientSocket.getOutputStream();
File myfile = new File("E:\\ "+file_to_upload);
byte[] mybytearray = new byte[(int) myfile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
bis.read(mybytearray, 0, mybytearray.length);
outtoserver.write(mybytearray, 0, mybytearray.length);
System.out.println("filename:"+file_to_upload+"Arrays on client while uploading:"+Arrays.toString(mybytearray));
outtoserver.flush();
bis.close();
}
catch(FileNotFoundException fe){fe.printStackTrace();}
catch(IOException ie){ie.printStackTrace();}
}
public static boolean searching(String file_name)
{
String file_path = "E:\\ "+file_name;
File f = new File(file_path);
if(f.exists() && !f.isDirectory()) { return true; }
else
return false;
}
}
The above code runs fine for transferring files between the client and server.
Again , would really appreciate any help!
There are many ways which you can do this, I suggest you to create a separate type of request to the server that accepts the file's name and file position which is the position where in the file where the connection failed.
That's how you will get the file from the server in the client's side:
int filePosition = 0;
InputStream is = clientSocket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
do {
baos.write(mybytearray);
bytesRead = is.read(mybytearray);
if(bytesRead != -1)
filePosition += bytesRead;
}
while (bytesRead != -1);
Now if the connection got interrupted for some reason you can send a request again to the server with the same file name and the filePosition, and the server will send the file back like this:
OutputStream outToClient = socke.getOutputStream();
// The file name needs to come from the client which will be put in here below
File myfile = new File("D:\\ "+file_name);
byte[] mybytearray = new byte[(int) myfile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
bis.skip(filePosition) //Advance the stream to the desired location in the file
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0, mybytearray.length);
System.out.println("Arrays on server:"+Arrays.toString(mybytearray));
outToClient.flush();
bis.close();
And in the client you can open the file stream and specify append = true in the constructor like this:
FileOutputStream fos = new FileOutputStream("D:\\ "+file_name, true);
This could be one way to do this, there are a lot more options. And I also suggest verify the files after the transfer using some hash function like MD5 for example, it creates unique stamp for a given input and it always outputs same result for the same input, which means, you can create the stamp from the same file both in the server and in the client and if the file is truly the same, it will generate the same stamp. Since the stamp's size is very small relative to the file it self and it is also fixed, it can be send between the client/server without much overhead.
You can generate an MD5 hash with this code:
MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"))) {
DigestInputStream dis = new DigestInputStream(is, md);
/* Read stream to EOF as normal... */
}
byte[] digest = md.digest();
(taken from: Getting a File's MD5 Checksum in Java)
Basically, when requesting a download You should attach information about how many bytes need to be skipped (0 on new download). You should get this information from part of the file that you have downloaded (read it's size). Server should skip given count of bytes and send back the remainder of file. Client should append this to the existing file. For sanity check, You could add some file hash checking in the end, to ensure You got the file correctly.

Reading Http Get request from a inputstream and sending it to the host. using sockets

i have this assignment where i am supposed to write a proxy server that uses java sockets to handle get requests from a client. I am now stuck and have been looking all over google to find the answer but without success.
Christoffers solution helped my with my first problem. Now that i have updated the code this is what i am using.
The problem is that it only downloads parts of most webpages before it gets stuck on sending the packets back to the client loop. At the moment I cant explain why it is behaving the way it is.
public class MyProxyServer {
//Set the portnumber to open socket on
public static final int portNumber = 5555;
public static void main(String[] args){
//create and start the proxy
MyProxyServer myProxyServer = new MyProxyServer();
myProxyServer.start();
}
public void start(){
System.out.println("Starting MyProxyServer ...");
try {
//create the socket
ServerSocket serverSocket = new ServerSocket(MyProxyServer.portNumber);
while(true)
{
//wait for a client to connect
Socket clientSocket = serverSocket.accept();
//create a reader to read the instream
BufferedReader inreader = new BufferedReader( new InputStreamReader(clientSocket.getInputStream(), "ISO-8859-1"));
//string builder for preformance when we loop over the inputstream and read lines
StringBuilder builder = new StringBuilder();
String host = "";
for (String buffer; (buffer = inreader.readLine()) != null;) {
if (buffer.isEmpty()) break;
builder.append(buffer.replaceAll("keep-alive", "close"));
if(buffer.contains("Host"))
{
//parse the host
host = buffer.replaceAll("Host: ", "");
}
System.out.println(buffer);
}
String req = builder.toString();
System.out.println("finshed reading \n" + req);
System.out.println("host: " + host);
//new socket to send the information over
Socket s = new Socket(InetAddress.getByName(host), 80);
//printwriter to send text over the output stream
PrintWriter pw = new PrintWriter(s.getOutputStream());
//send the request from the client
pw.println(req+"\r\n");
pw.flush();
//create inputstream to receive the web page from the host
BufferedInputStream in = new BufferedInputStream(s.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outbuffer = new BufferedOutputStream(clientSocket.getOutputStream());
byte[] bytebuffer = new byte[1024];
int bytesread;
//send the response back to the client
while((bytesread = in.read(bytebuffer)) != -1) {
System.out.println(bytesread);
outbuffer.write(bytebuffer,0, bytesread);
outbuffer.flush();
}
System.out.println("done sending");
//close the streams
inreader.close();
s.close();
pw.close();
outbuffer.close();
in.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch(RuntimeException e){
e.printStackTrace();
}
}
}
If anyone could explain to me why i cant get it working correctly and how to solve it I would be very grateful!
Thanks in advance.

Sending name of the file then file itself

I want to make my server to be able to get the name of the file that will be sent to it and then after getting that file it could save it in new location with right name.
Here is the server code:
class TheServer {
public void setUp() throws IOException { // this method is called from Main class.
ServerSocket serverSocket = new ServerSocket(1991);
System.out.println("Server setup and listening...");
Socket connection = serverSocket.accept();
System.out.println("Client connect");
System.out.println("Socket is closed = " + serverSocket.isClosed());
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String str = rd.readLine();
System.out.println("Recieved: " + str);
rd.close();
InputStream is = connection.getInputStream();
int bufferSize = connection.getReceiveBufferSize();
FileOutputStream fos = new FileOutputStream("C:/" + str);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
bos.flush();
bos.close();
is.close();
connection.close();
serverSocket.close();
}
}
and here is the client code:
public class TheClient {
public void send(File file) throws UnknownHostException, IOException { // this method is called from Main class.
Socket socket = null;
String host = "127.0.0.1";
socket = new Socket(host, 1991);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
wr.write(file.getName());
wr.flush();
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();
}
}
I made few test of my own and it seems that my client is sending the name of the file right, but somehow server gets it wrong. For example if my client tells that name of the file is "test.txt" my server gets it for example like "test.txt´--------------------" or "test.txtPK". I can't understand why it does't get the name normally. Anyone knows why this happens? Or is there an easier way to do this? And my second question is, how can I use this not only in localhost but everywhere? I tried changing my host to my IP adress but it didnt work. Thanks.
You never send end of line after the filename. Therefore, when server reads using readLine() it will read all characters until it find first end of line which may be somewhere in file content. Sometimes it's after '-----' and sometimes after 'PK'.

Categories