Java TCP Server read file name - java

I want to create small client-server TCP file transfer program. And I have problem with one thing. When I send file from Client to Server, for example a txt file: omg.txt, I want the Server to read the incoming file name.
So - Client send omg.txt, Server says "New file recived: omg.txt". I tried to use BufferedReader (Server) and DataOutputStream (Client, because you have to write name of the file to send it) but it didnt work.
EDIT:
Client:
Socket sock = new Socket("localhost",13267);
System.out.println("Wait...");
Scanner input = new Scanner(System.in);
while(true){
// wysylanie
System.out.println("Filename");
String p = input.nextLine();
File myFile = new File (p);
boolean exists = (new File(p)).exists();
if (exists) {
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream());
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Wait...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done");
sock.close();
}
Server:
int filesize=6022386;
int bytesRead;
int current = 0;
ServerSocket servsock = new ServerSocket(13267);
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("Wait...");
Socket sock = servsock.accept();
System.out.println("OK : " + sock);
// odbior pliku
byte [] mybytearray = new byte [filesize];
InputStream is = sock.getInputStream();
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
System.out.println("New filename");
String p = input.nextLine();
File plik = new File(p);
FileOutputStream fos = new FileOutputStream(plik);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("File saved");
bos.close();
sock.close();
And I tried to do something like that:
Client addon:
DataOutputStream outToServer = new DataOutputStream(sock.getOutputStream());
sentence = input.nextLine();
outToServer.writeBytes(sentence);
Server addon:
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(sock.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println(clientSentence);
...but unfortunetly I have "Wait.." all the time for Client

TCP just transfers raw data. If you want to send files with a filename, you may want to use a higher level protocol, such as FTP or TFTP.
If you really want to use plain TCP, you'll need to encode the filename in your message somehow. You could, for example, send the filename as the first line of the message, and then have the other end turn the rest of the message into a file with that name.
This may be helpful to you: http://www.adp-gmbh.ch/blog/2004/november/15.html

Related

Can't open received amr/jgp file from socket on android

To send and receive file via socket over Wifi I have used following code...
Client side :
Socket socket = new Socket(dstAddress, dstPort);
int bufferSize=socket.getReceiveBufferSize();
InputStream in=socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF();
System.out.println(fileName);
OutputStream output = new FileOutputStream("/sdcard/"+fileName);
byte[] buffer = new byte[bufferSize];
int read;
while((read = clientData.read(buffer)) != -1){
output.write(buffer, 0, read);
}
//close every thing
output.flush();
output.close();
socket.close();
Server side:
File file = new File(Environment.getExternalStorageDirectory(), "/sdcard/test.amr");
byte[] mybytearray = new byte[8092];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os;
try {
os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
dos.writeLong(mybytearray.length);
int read;
while((read = dis.read(mybytearray)) != -1){
dos.write(mybytearray, 0, read);
}
os.flush();
os.close();
socket.close();
At this point I am receiving file 'test.amr' from server without change of its original size.
But when I try to play the file in client device it can't be played.
Note : mp3, avi and txt file received using above code can be opened and played perfectly.
Please suggest how to solve this issue.
Finally I have solved the above problem by just removing
dos.writeLong(mybytearray.length);
line form server code...
as per suggestion of greenapps.
My revised server code is:
File file = new File(Environment.getExternalStorageDirectory(), "/sdcard/test.amr");
byte[] mybytearray = new byte[8092];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os;
try {
os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
int read;
while((read = dis.read(mybytearray)) != -1){
dos.write(mybytearray, 0, read);
}
os.flush();
os.close();
socket.close();
You're writing the buffer size as a long but you're not reading it. So the long is being read as part of the image. As writing your sending buffer size has no conceivable relevance to the receiver, you should remove the writeLong(mybytearray.length) call from the sender.

java tcp server to android device

i am trying to make a java server that will send images stored in a database to android device.
for now am trying with simple image that stored on the hard disk for the server to send.
my question is can i send an image from java server as a byte array to android via TCP sockets.
Yes, you can, using TCP sockets.
Read the file as bytes and send it as bytes, don't try to load it as a BufferedImage.
Then, on the receiving end, use a function that allows you to load an image from an array of bytes.
Sure, you can, but you will need to invent your own protocol for that. You may find using HTTP more, either setting up a web-server like Tomcat with your application deployed there, or use something embedded like Jetty
The fastest and easiest approach for sending image is as follows...
Try this
// Server Side code for image sending
ServerSocket servsock = new ServerSocket(13250);
System.out.println("Main Waiting...");
Socket sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
File myFile = new File ("\sdcard\ab.jpg");
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);*/
byte [] mybytearray =new byte[count];
System.arraycopy(Copy, 0, mybytearray, 0, count);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
sock.close();
servsock.close();
//Client side code for image reception
try
{
int filesize=6022386; // filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
// localhost for testing
ServerSocket servsocket = new ServerSocket(13267);
System.out.println("Thread Waiting...");
Socket socket = servsocket.accept();
System.out.println("Accepted connection : " + socket);
System.out.println("Connecting...");
File f=new File("\sdcard\ab.jpg");
f.createNewFile();
// receive file
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
count=current;
Copy=mybytearray.clone();
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
fos.close();
socket.close();
servsocket.close();
}
} catch(IOException e)
{
System.out.println("errorr");
}

how to stop socket keeps writing data in loop java

I have made server client application where server will send a file to client and client will receive it and save it in C:/ on any place.
I first send a string "File" in order to tell client to receive file and than server send file name and size to client and then start sending it.
Problem is that client doesnt receive file although it read in loop and get all bytes but doesnt write to required file object. Please have a look on client code I HAVE SHOWN WHERE IT STUCKS
Following is server code :
public void run(){
try{
System.out.println("Starting writing file");
objOut.writeObject("File");
objOut.flush();
File f= new File(filePath);
String name= f.getName();
int length =(int) f.length();
objOut.writeObject(name);
objOut.flush();
objOut.writeObject(length);
objOut.flush();
byte[] filebytes = new byte[(int)f.length()];
FileInputStream fin= new FileInputStream(f);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(filebytes, 0, filebytes.length);
BufferedOutputStream bout = new BufferedOutputStream(objOut);
bout = new BufferedOutputStream(objOut);
bout.write(filebytes, 0, filebytes.length);
bout.flush();
System.out.println("File completelty sent");
}
catch(Exception ex)
{
System.out.println("error on writing file : "+ex.getMessage());
}
}
Following is client code :
while(true){
fobjIn = new ObjectInputStream(fileSock.getInputStream());
String str = (String) fobjIn.readObject();
if(str.equals("File"))
{
System.out.println("Starting receiving file");
ReceiveFile();
}
System.out.println(str);
}
public void ReceiveFile() throws Exception{
String name =(String)fobjIn.readObject();
File f = new File("C:/Temp/" +name);
f.createNewFile();
int length = (int) fobjIn.readObject();
FileOutputStream fout = new FileOutputStream(f);
BufferedOutputStream buffout = new BufferedOutputStream(fout);
byte[] filebyte = new byte[length];
int bytesRead=0,current=0;
bytesRead = fobjIn.read(filebyte, 0, filebyte.length);
do {
bytesRead = fobjIn.read(filebyte, current, (filebyte.length-current));
if(bytesRead > 0) {
current += bytesRead;
System.out.println("writting" + bytesRead);
}
else break;
} while(bytesRead > -1);
^^^^^^^IT DOESNT COMEOUT FROM LOOP while begugging^^^^^^^^
buffout.write(filebyte, 0 , current);
buffout.flush();
System.out.println("written");
}
You should probably close your stream on the server side when you are done sending, so that the client can be notified that the server is done sending. Or else it'll just sit there waiting for more data.

Socket Programming file upload issues?Complete file not uploading

Hi i am using the following code for uploding my file from android phone to the server bt the file does not upload completely..e.g i uploded a 11kb file and got only 8kb file at the server.What am i doing wrong?
Client side
Socket skt = new Socket"112.***.*.**", 3000);
String FileName=fil.getName();
PrintWriter out2 = new PrintWriter(new BufferedWriter(new OutputStreamWriter(skt.getOutputStream())),true);
out2.println("Upload");
out2.println(FileName);
out2.println(spinindx);
out2.println(singleton.arrylst_setngs.get(0).toString());
out2.println(singleton.arrylst_setngs.get(1).toString());
out2.println(singleton.arrylst_setngs.get(2).toString());
out2.println(singleton.arrylst_setngs.get(3).toString());
out2.println(singleton.arrylst_setngs.get(4).toString());
out2.flush();
//Create a file input stream and a buffered input stream.
FileInputStream fis = new FileInputStream(fil);
BufferedInputStream in = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(skt.getOutputStream());
//Write the file to the server socket
int i;
byte[] buf = new byte[512];
while ((i = in.read(buf)) != -1) {
out.write(buf,0,i);
publishProgress(in.available());
System.out.println(i);
}
//Close the writers,readers and the socket.
in.close();
out.flush();
out.close();
out2.close();
skt.close();
}
catch( Exception e ) {
System.out.println(e);
}
The server side
InputStream inStream = socket.getInputStream();
BufferedReader inm = new BufferedReader(new InputStreamReader(inStream));
String Request=inm.readLine();
if(Request.equals("Upload")){
fileName = inm.readLine();
chosn = inm.readLine();
lt=inm.readLine();
cs = inm.readLine();
om = inm.readLine();
o = inm.readLine();
check=inm.readLine();
//Read, and write the file to the socket
BufferedInputStream in = new BufferedInputStream(inStream);
int i=0;
File f=new File("D:/data/"+filePrefx+fileName);
if(!f.exists()){
f.createNewFile();
}
FileOutputStream fos = new FileOutputStream("D:/data/"+filePrefx+fileName);
BufferedOutputStream out = new BufferedOutputStream(fos);
byte[] buf = new byte[512];
while ((i = in.read(buf)) != -1) {
System.out.println(i);
out.write(buf,0,i);
System.out.println("Receiving data...");
}
in.close();
inStream.close();
out.close();
fos.close();
socket.close();
Looks like you are using both a BufferedReader and a BufferedInputStream on the same underlying socket at the server side, and two kinds of output stream/writer at the client. So your BufferedReader is buffering, which is what it's supposed to do, and thus 'stealing' some of the data you're expecting to read with the BufferedInputStream. Moral: you can't do that. Use DataInputStream & DataOutputStream only, and writeUTF()/readUTF() for the 8 lines you are reading from the client before the file.
You shared the same underlying InputStream between your BufferedReader and bufferedInputStream.
What happened is, when you do the reading through BufferedReader, it reads more than the a few lines you requested from the underlying InputStream into its own internal buffer. And when you create the BufferedInputStream, the data has already been read by the BufferedReader. So Apart from what EJP suggested not to use any buffered class, you can create the BufferedInputStream, and then create the Reader on Top of it. The code is something like this:
BufferedInputStream in = new BufferedInputStream(inStream);
Reader inm = new InputStreamReader(in);
Add it to the beginning of your server code and remove this line:
BufferedInputStream in = new BufferedInputStream(inStream);
See this, i never tried though
void read() throws IOException {
log("Reading from file.");
StringBuilder text = new StringBuilder();
String NL = System.getProperty("line.separator");
Scanner scanner = new Scanner(new FileInputStream(fFileName), fEncoding);
try {
while (scanner.hasNextLine()){
text.append(scanner.nextLine() + NL);
}
}
finally{
scanner.close();
}
log("Text read in: " + text);
}
Shamelessly copied from
http://www.javapractices.com/topic/TopicAction.do?Id=42

Java sending files through sockets

I want to send files as well as some other information through sockets. I am using the following code
public void receiveFile(Socket socket,int filesize,String filename) throws IOException
{
//after receiving file send ack
System.out.println("waiting ");
// int filesize=70; // filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
// localhost for testing
System.out.println("Connecting...");
// receive file
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(filename);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
System.out.println("recv..."+mybytearray.length);
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
System.out.println(bytesRead);
if(bytesRead > 0) current += bytesRead;
} while(bytesRead > 0);
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
System.out.println(" File received");
}
After receiving the file, I have to receive some other strings. But when I try to read the input stream, I am getting the contents of the file. How to flush the contents of the file from the inputstream.
BufferedReader inFromServer =
new BufferedReader(new InputStreamReader(
webServerSocket.getInputStream()));
receiveFile(webServerSocket,filesize,filename);
while(true)
{
msg = inFromServer.readLine(); //here i receive the contents of the file again
System.out.println(msg);
}
Pass the socket's inputstream to the receivefile-method, instead of the socket itself:
InputStream is = webServerSocket.getInputStream();
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(is));
receiveFile(webServerSocket,filesize,filename);
The problem lies, I believe, in the fact that you have two inputstreams from the same socket made at the same point in time (before any data has actually been read). They point to the same stream but reading from one does not move the other as well, thus after reading from inputstreamBA that one is marked in position 15 (for example) while inpustream A is still in poisition 0, at the beginning of the stream.
(EDIT:)
Ofcourse, you have to use the inputstream in the receiveFile method instead of getting one from the socket. Another solution would be to get the inputstream from the socket after the call to receive file, as in
receiveFile(webServerSocket,filesize,filename);
BufferedReader inFromServer =
new BufferedReader(new InputStreamReader(webServerSocket.getInputStream()));
By reading the file to completion, you will have read the whole file. If you are still getting the contents of the file, you haven't read the whole file.

Categories

Resources