Failed to send data stream by sockets in Java - java

I'm trying to stream audio through TCP sockets in java, using the Java sound api.
Up there all right, the problem comes when the client will play that data buffer that comes from the server, when entering the play method, automatically shows the following error:
Exception in thread "main" javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1121)
at AudioClient.play(AudioClient.java:37)
at AudioClient.main(AudioClient.java:18)
I do not know why he shows it, or what I'm doing wrong.
This is the server code, which looks for the file and sends it to the client
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class AudioServer {
public static void main(String[] args) throws IOException {
File soundFile = AudioUtil.getSoundFile("C:\\Users\\Carlos\\Desktop\\03- Walk.wav");
System.out.println("server: " + soundFile);
try (ServerSocket serverSocker = new ServerSocket(6666);
FileInputStream in = new FileInputStream(soundFile)) {
if (serverSocker.isBound()) {
Socket client = serverSocker.accept();
OutputStream out = client.getOutputStream();
byte buffer[] = new byte[2048];
int count;
while ((count = in.read(buffer)) != -1)
out.write(buffer, 0, count);
}
}
System.out.println("server: shutdown");
}
}
And this is the client code, which captures that data flow and reproduces it
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.Socket;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class AudioClient {
public static void main(String[] args) throws Exception {
// play soundfile from server
System.out.println("Client: reading from 192.168.0.19:6666");
try (Socket socket = new Socket("192.168.0.19", 6666)) {
if (socket.isConnected()) {
InputStream in = new BufferedInputStream(socket.getInputStream());
play(in);
}
}
System.out.println("Client: end");
}
private static synchronized void play(final InputStream in) throws Exception {
AudioInputStream ais = AudioSystem.getAudioInputStream(in);
try (Clip clip = AudioSystem.getClip()) {
clip.open(ais);
clip.start();
Thread.sleep(100); // given clip.drain a chance to start
clip.drain();
}
}
}
Additionally, there is an AudioUtils class, which only contains a static method, this static method only throws an exception in case the file passed by the programmer is not a file or does not exist. The code is the following
import java.io.File;
public class AudioUtil {
public static File getSoundFile(String fileName) {
File soundFile = new File(fileName);
if (!soundFile.exists() || !soundFile.isFile())
throw new IllegalArgumentException("not a file: " + soundFile);
return soundFile;
}
}
It should also be clarified that both classes, both server and controller have the proncipal method because they are 2 separate programs. My question is, how do I solve this error, I really do not know where to start. Thank you

Related

java: Transfer a file to the server and get the file from the server in upper case

i want to send a .txt file from the client to server and get it back in upper case.
But this code do nothing.can anyone tell what is wrong here..?
SERVER : getting file from client and sending it back in upper case to the client.
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
public class Assignment4_Server {
public static void main(String[] args) throws IOException {
byte[] bytearray = new byte[4096];
try (ServerSocket ss = new ServerSocket(4444)) {
Socket s = ss.accept();
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
int count;
String data = null ;
while((count = is.read(bytearray))>0){
data = Arrays.toString(bytearray).toUpperCase();
byte[] bytearrayout = data.getBytes();
os.write(bytearrayout);
}
s.close();
}
}
}
CLIENT : sending text.txt file to the server and getting file back after converted in upper case.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Assignment4_client {
public static void main(String[] args) throws IOException {
File file = new File("test.txt");
byte[] bytearray = new byte[4096];
Socket sc = new Socket("localhost",4444);
//send file
int countS , countR;
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = sc.getOutputStream();
while((countS = bis.read(bytearray))>0){
os.write(bytearray);
}
//recieve file in uppercase from server
InputStream is = sc.getInputStream();
byte[] bytearray2 = new byte[4096];
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
while((countR = is.read(bytearray2))>0){
bos.write(bytearray2);
}
}
}
Here is a code that should help you. But before reading it you should be aware of what is happening:
Your client is not sending a 'stop reading' information to the server (read the client code below). That's why the server is stuck in the while loop when it is trying to read the data sent by the client. That is probably why you have tried to send the data back directly to the client. Shut down the socket output from the client side to respect the Socket contract and correctly free the socket (see TCP/IP).
The solution given doesn't take in account that the server should stay up after it has done its duty. Then, the server will not be able to serve more than one client at a time. This server is offering a one time service, which is pointless. To overcome this issue you should put everything in a while loop and bind every new server process into a new thread (I let you do that, its quite a joy).
The server doesn't take in account the whole size of the data an it could possibly run into an out of memory error if the data is too heavy. You should find a way to avoid this problem in a real implementation.
Both program should catch the exception and log it somewhere so you could be aware of any errors.
Writing a server is not so simple. You should normally write some kind of protocol with headers and other stuff like that. To avoid that, use objects like ObjectOutputStream and ObjectInputStream but it has some limitation like constraining your server in the Java world.
CLIENT
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
public class Client {
public void send(File file)
{
Socket sc = null;
try
{
byte[] bytearray = new byte[4096];
sc = new Socket("localhost", 4444);
// 1. Read the file, send its content, close it.
int count;
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = sc.getOutputStream();
while((count = bis.read(bytearray))>0)
{
os.write(bytearray);
}
fis.close();
sc.shutdownOutput();
// 2. Delete old file, receive data, write it to new File.
InputStream is = sc.getInputStream();
bytearray = new byte[4096];
// Eventually do what you want with the file: new one, append, etc.
file.delete();
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
count = 0;
while((count = is.read(bytearray)) > 0)
{
bos.write(bytearray, 0, count);
}
fos.close();
bos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (sc != null)
{
try
{
sc.close();
} catch (IOException e) {}
}
}
}
}
SERVER
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
Server()
{
Socket s = null;
byte[] bytearray = new byte[4096];
try (ServerSocket ss = new ServerSocket(4444))
{
s = ss.accept();
InputStream is = s.getInputStream();
// 1. Recieve data and put it to UpperCase.
String data = "";
int count;
while((count = is.read(bytearray)) > 0)
{
data += new String(bytearray, 0, count);
}
data = data.toUpperCase();
System.out.println(data);
// 2. Send back data.
OutputStream os = s.getOutputStream();
os.write(data.getBytes());
os.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
TEST PROGRAM
This one should help you to test your both programs in the same project in an IDE.
import java.io.File;
public class Test
{
public static void main(String[] args)
{
Client c = new Client();
(new Thread()
{
public void run()
{
Server s = new Server();
}
}).start();
c.send(new File("test.txt"));
}
}
What is wrong here is two simple things.
The server is reading until end of stream, on a socket that must be used for the reply. The client therefore cannot close it after sending the request to provide the EOS, so it must shutdown the socket for output after sending the request.
Your copy loops are wrong. The general form is:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
You are ignoring the read count when writing, so you will write junk at end of stream, or any other time that read() doesn't fill buffer, which can be any time at all.

Java: Bytes are not transferred correctly

I've made a server that should let the client udpate a file. All in all it is working, but some bytes, for example HEX 9D is getting to HEX 3F. I have no more ideas and didn't find anything on the web. My server code:
package de;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class UpdateThread extends Thread {
public UpdateThread(Socket s) {
socket = s;
}
public void run() {
try {
execute();
} catch (IOException e) {
e.printStackTrace();
}
}
#SuppressWarnings("resource")
public void execute() throws IOException {
if (UpdateProvider.update) {
int i = 0;
SocketTools.sendData(1, socket);
File file = new File("." + System.getProperty("file.separator").toString() + "update_package.jar");
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
FileReader reader = new FileReader(file);
while ((i = reader.read()) != -1) {
writer.write(i);
}
writer.flush();
writer.close();
} else {
SocketTools.sendData(0, socket);
}
}
private Socket socket;
}
And my client code:
package de;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Main {
#SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
Socket s = new Socket("localhost", 16642);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
//InputStreamReader reader = new InputStreamReader(s.getInputStream());
int i = 0;
FileWriter writer = new FileWriter(new File("C:\\update_package.jar"));
int state = reader.read();
if (state == 48) {
System.exit(0);
}
if (state == 49) {
while ((i = reader.read()) != -1) {
System.out.println(i);
writer.write(i);
}
System.out.println("ENDE");
writer.flush();
}
}
}
You're not specifying a proper encoding for the transmission (you should use InputStream/OutputStreams instead of Reader/Writer for this anyways, since you're handling binary data and not text). 0x3F is the questionmark '?', meaning that a non-ASCII character (128 or higher) has been converted.
So lose the Readers and Writers and go with Streams.
Encoding is needed for text files only. I looked at your source code. You are trasferring a jar, which is a binary file, not text. If you use use text processing classes for binary data, you can get a lot of unpredictable transformations. Don't use OutputStreamWriter. Use socket.getOutputStream() directly:
OutputStream = socket.getOutputStream();
...
out.write(...);
Same for client. Don't use InputStreamReader. Use s.getInputStream() directly:
InputStream in = s.getInputStream();
...
in.read(...);

java.io.EOFException error on object serialization with HttpHandler

I am trying to serialize an object in a HttpHandler class.
I have 2 files, Server3.java:
package server3;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Server3 {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(3333), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
String response = "Kjo eshte nje pergjigje nga serveri! n";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
Personat obj = new Personat();
ObjectOutputStream objOut = new ObjectOutputStream(t.getResponseBody());
objOut.writeObject(obj);
objOut.close();
}
}
}
class Personat implements Serializable{
private static final long serialVersionUID = 1L;
int ID=3;
String Name="Andi";
}
and Client3.java:
package server3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
//te gjithe personat qe jan ne database me nej objekt
public class Client3 {
public static void main(String[] args) throws Exception {
try {
URL url = new URL("http://localhost:3333");
HttpURLConnection s = (HttpURLConnection) url.openConnection();
s.setDoOutput(true);
s.setDoInput(true);
s.setRequestMethod("POST");
s.setUseCaches(false);
InputStream in = s.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
int c;
while ((c = br.read()) != -1) {
System.out.print((char) c);
}
ObjectInputStream ios = new ObjectInputStream(s.getInputStream());
Personat oin = (Personat) ios.readObject();
String emri=oin.Name;
System.out.println(emri);
ios.close();
s.disconnect();
} catch (IOException ex) {
System.err.println(ex);
System.out.print(ex);
}
}
}
But when I run it eclipse shows me
java.io.EOFException Kjo eshte nje pergjigje nga serveri! njava.io.EOFException`
and I cant understand why.
The problem is that you are trying to fit both the string response and the object into response.length() bytes. What happens is that only response.length() bytes are sent and so if you try to read more you get the EOFException.
If you instead set the responseLength parameter to be 0 it will allow you to transmit an arbitrary amount of data
t.sendResponseHeaders(200, 0);
You also shouldn't close the stream if you are going to write more data into it. Don't call os.close() until all the writing is complete.

not able to get inputstream in server socket file transfer

I have developed a screen in swings to download a file from the server. The whole concept works fine when i click the download button once. But when i click the download button second time, i find that the code pauses in getting the inputstream.(this i have followed it using the sysouts shown.)
Below shown are the two separate code snippets in two different files. TCPClient has the serversocket codings whereas the clientUI has the ui components which calls the TCPSever method to accept a socket and for requesting purpose.
In the tcp client side:
public TCPClient() throws Exception{
System.out.println("Inside TCPClient constructor---");
clientSocket = new Socket("localhost", 3500);
System.out.println("After creating socket instance---");
oos = new ObjectOutputStream(clientSocket.getOutputStream());
System.out.println("after getting the ouput stream---");
ois = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("after getting the input stream.");
}
In the Client UI:
private void downloadButton_actionPerformed(ActionEvent e) throws Exception
{
Object selectedItem = contentsList.getSelectedValue();
System.out.println("selectedItem---"+selectedItem);
new TCPClient().downloadContents(nodeName,selectedItem.toString());
}
}
Kindly provide me a solution for this...
Below is the server code:
public void listening() throws Exception{
ServerSocket ss = new ServerSocket(3500);
System.out.println( "DataServer Is Listening..." );
while( true )
{
Socket soc = ss.accept();
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream( soc.getOutputStream() );
String input = ( String ) ois.readObject( );
if(input.startsWith("downloadContents")){
String nodeName = ois.readObject().toString();
String contentName = ois.readObject().toString();
List contentsForNode = DBServer.getContentsForNode(nodeName);
for(Object obj : contentsForNode){
if(obj.toString().contains(contentName)){
new FileServer().send(obj.toString());
break;
}
}
}
}
}
public static void main( String[] args )
{
TCPServer obDataServer = new TCPServer();
try
{
obDataServer.listening();
}
catch ( Exception ioe )
{
ioe.printStackTrace();
}
}
At a guess, your server is single-threaded and is still reading its input stream, because you haven't closed the client socket. But it's anybody's guess until you post the relevant server code.
Do you take care of closing the socket after the file is downloaded (successfully/unsuccessfully)? It doesn't looks like it from the code snippet.
I'm not sure, but this might be the problem
This Is Server Class:
package client_to_server;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;`
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Server {
public static void main(String args[])throws IOException
{
ServerSocket serverSocket=new ServerSocket(2222);
System.out.println("New Server is Waiting");
Socket socket=serverSocket.accept();
System.out.println("My Connection Established");
DateFormat df=new SimpleDateFormat("HH:mm:ss");
Calendar c=Calendar.getInstance();
String starttime=df.format(c.getTime());
System.out.println("Start time is : "+starttime);
InputStream inputStream=socket.getInputStream();
byte[] readbyte=new byte[(1024*20)*1024];
FileOutputStream fileOutputStream=new FileOutputStream("/home/Manoj/copybulkfile5.zip");
int writebyte;
int count=0;
while((writebyte=inputStream.read(readbyte))!=-1)
{
if(writebyte>0)
count+=writebyte;
fileOutputStream.write(readbyte, 0, writebyte);
}
DateFormat df1=new SimpleDateFormat("HH:mm:ss");
Calendar c1=Calendar.getInstance();
String endtime=df1.format(c1.getTime());
System.out.println("END TIME is "+endtime);
System.out.println("THE WRITEBYTE VALUE IS "+writebyte+"THE READ BYTE VALUE IS"+count);
inputStream.close();
}
}
This Is Client Cass:
package client_to_server;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String args[])throws IOException
{
//Socket socket=new Socket("localhost",2222);
Socket socket=new Socket("localhost",2222);
File file=new File("/home/Checking/Myfile.zip");
byte[] mybyte=new byte[(1024*20)*1024];
FileInputStream fileInputStream=new FileInputStream(file);
int count;
OutputStream outputStream=socket.getOutputStream();
while((count=fileInputStream.read(mybyte))!=-1)
{
outputStream.write(mybyte);
}
System.out.println("THIS FILE HAS BEEN SENT SUCCESSFULLY!!!");
//System.out.println("END TIME "+hr+"Hours"+min+"Minutes "+sec+"Seconds");
socket.close();
}
}

Object Input Stream only getting one file over network?

I have created a basic Client Server that will send image files in a specified directory over a network. The code worked last week but I came back to it today and it seems that I am only getting one file on the server side, even though the client prints out that it has sent all the image files in the directory.
It may be something in the client code but I think it is something on the server side.
Any help is greatly appreciated and if you have a more efficient solution, I am happy to change my code as necessary. My code is below:
ImageServer
package com.encima.network.server;
import java.io.*;
import java.net.*;
public class ImageServer{
ServerSocket ss;
Socket s;
ObjectOutputStream oos;
int port = 4440;
public ImageServer() throws IOException {
try {
ss = new ServerSocket(port);
System.out.println("Server started on Port: " + port);
} catch(IOException e) {
System.out.println("Serevr: Port-" + port + " not available, exiting.");
System.exit(0);
}
System.out.println("Server: Waiting for Client Connection...");
while(true) {
try {
s = ss.accept();
new ImageHandler(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
ImageServer is = new ImageServer();
}
}
ImageHandler
package com.encima.network.server;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import javax.imageio.ImageIO;
public class ImageHandler implements Runnable {
Socket s;
int count = 0;
public ImageHandler(Socket socket) {
s = socket;
Thread t = new Thread(this);
t.start();
}
#Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
FileOutputStream fos = new FileOutputStream("image" + System.nanoTime() + ".jpg");
count++;
//BufferedImage in = ImageIO.read(ois);
//ImageIO.write(in, "jpg", fos);
int ch = 0;
while(true) {
ch = ois.read();
if(ch == -1) {
break;
}
fos.write(ch);
}
fos.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Finally, the ImageClient
package com.encima.network.client;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.imageio.ImageIO;
import com.encima.network.ImageFilter;
public class ImageClient {
Socket s;
String ip = "localhost";
int port = 4440;
ObjectOutputStream oos;
public ImageClient(File[] files) throws IOException, ClassNotFoundException, InterruptedException {
try {
s = new Socket(ip, port);
System.out.println("Client connected to Server via " + ip + " on port 80");
} catch (Exception e) {
System.out.println("Client: Cannot find Host: " + ip + ". Exiting.");
System.exit(0);
}
oos = new ObjectOutputStream(s.getOutputStream());
for(File f: files) {
sendFile(f);
}
oos.close();
//System.out.println("Written Image " + i + " of " + files.length);
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
File dir = new File("/Users/christophergwilliams/Dropbox/PhD/Projects/PhD/Year 1/GSN/images");
File[] files = dir.listFiles(new ImageFilter());
ImageClient ic = new ImageClient(files);
}
public void sendFile(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
//BufferedImage b = ImageIO.read(file);
//ImageIO.write(b, "jpg", oos);
int ch = 0;
while(true) {
ch = fis.read();
if(ch == -1) {
break;
}
oos.write(ch);
}
oos.flush();
System.out.println("Image Sent");
}
}
I am aware that it is a lot of code to read through but I do appreciate any help I can get on this!
I may be wrong but, for the sake of efficiency and network traffic, would it be beneficial to send the images as a zip from the client to the server?
Why are you using ObjectInputStream at all? You're not reading or writing any serialized objects - just raw binary data. Use whatever InputStream is provided, and read from that.
Anyway, that's not the big problem. The big problem is that you're just writing several files to one stream, with no indication of where one file is meant to finish and the next one is meant to start. How were you expecting to split the multiple files up? Options:
Use a delimiter between files (very ugly - you'd have to potentially escape any data which looked like the delimiter as you went along)
Prefix each file with its length
Send each file on a different connection
(You're also reading and writing a single byte at a time. Use the overloads of read/write which accept byte arrays.)

Categories

Resources