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.
Related
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());
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();
}
}
The code works fine when I close the client just after sending one instruction. But when I want a client and server connection to persist, so that the client can send multiple instructions to the server one after another, I get a Null pointer exception at the server and the message java.net.SocketException: Socket is closed at the client. This happens after the client sends a file to the server and the server successfully receives it. Need help. The error occurs at the Connection class code line switch(clientMsg). It seems to me that for some reason the BufferedReader in goes null, but I might be mistaken about that. The code is as follows. Thanks.
Server
public class server {
private static ServerSocket serverSocket;
private static Socket socket = null;
public static void print(Object s) {
System.out.println(s);
}
#SuppressWarnings("resource")
public static void main (String args[]) throws IOException {
System.out.print("Specify listening port: ");
Scanner _a = new Scanner(System.in);
int a = _a.nextInt();
try{
serverSocket = new ServerSocket(a);
}
catch(IOException e) {
System.out.println(e);
}
while (true) {
try {
socket = serverSocket.accept();
print("Connected to " + socket);
Thread client = new Thread(new Connection(socket));
client.start();
}
catch (IOException e) {
print(e);
}
}
}
}
Connection
public class Connection implements Runnable {
public static void print(Object s) {
System.out.println(s);
}
private Socket socket;
private BufferedReader in = null;
public Connection(Socket client) {
this.socket = client;
}
#Override
public void run(){
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String clientMsg;
while (true) {
clientMsg = in.readLine();
switch (clientMsg) {
case "1":
receiveFile(); //method code not included
break;
default:
print("Command not recognized");
break;
}
//in.close();
}
}//try run()
catch (IOException e) {
print(e);
}
}
Client
public class client {
private static Socket connectToServer;
private static String fileName;
private static BufferedReader keybrdIn;
private static PrintStream msgToServer;
public static void println(Object e) {
System.out.println(e);
}
public static void print(Object e) {
System.out.print(e);
}
public static void main(String args[]) throws IOException{
try{
print("Enter IP: ");
String ip = new Scanner(System.in).nextLine();
print("Enter port: ");
int port = new Scanner(System.in).nextInt();
connectToServer = new Socket(ip, port);
keybrdIn = new BufferedReader(new InputStreamReader(System.in));
}catch(IOException e) {
println(e);
}
msgToServer = new PrintStream(connectToServer.getOutputStream());
while (true) {
try {
switch(Integer.parseInt(action())) { //action() method code not included
case 1:
msgToServer.println("1");
sendFile();
break;
default:
println("Invalid input");
break;
}
}catch (IOException e) {
println(e);
}
}
}
sendFile()
public static void sendFile() throws IOException {
print("Enter file name: ");
fileName = keybrdIn.readLine();
File file = new File(fileName);
byte[] bytearray = new byte[8192];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os = connectToServer.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
int count;
while ((count = dis.read(bytearray)) > 0){
dos.write(bytearray, 0, count);
}
dis.close();
dos.flush();
dos.close();
}
receiveFile()
public void receiveFile() {
try {
int count;
DataInputStream clientFileStream = new DataInputStream(socket.getInputStream());
String fileName = clientFileStream.readUTF();
OutputStream fileOutput = new FileOutputStream("_" + fileName);
byte[] mybytearray = new byte[8192];
BufferedOutputStream bos = new BufferedOutputStream(fileOutput);
System.out.println("Downloading " + fileName + " ...");
//outToClient().writeBytes("Uploading. Please wait...\n");
while ((count = clientFileStream.read(mybytearray)) > 0){
bos.write(mybytearray, 0, count);
}
fileOutput.close();
bos.close();
clientFileStream.close();
}
catch (IOException e) {
print(e);
}
}
In sendFile(), you close the data output stream which closes your underlying connection's output stream.
According to the documentation of Socket.getOutputStream():
"Closing the returned OutputStream will close the associated socket".
Since you already closed stream, it will also close socket as well as Eyal mentioned. However, at the moment you close the stream, server side will aware of that and return -1 for read() results.
So, even if you didn't specify file length at beginning, this will generally works well.
However, since you already closed stream, you can't reuse it no matter what. To fix this issue, probably you need to change your Client class so that Client should create socket connection, send files, close socket. That's one lifecycle of opened client socket.
Or maybe in while loop of Client class, 1) take ip, port, and filename to send 2) Create new Thread and provide those information so let thread open connection, send file, close connection 3) and in the meantime, client while() can keep take next ip, port, and filename to send from the user. By doing this, you don't need to make client program wait until file transfer to be completed.
Regarding the NPE in the server, readLine() returns null at end of stream. You are ignoring it. You should be testing for it immediately after the call, and if null close the socket and exit the read loop.
I am trying to write the server client file transfer program in java.
Role of Server:-
a) Serve a file to a client (one).
b) Server will send file 1 byte at a time.
c) Should be able to send the file more than once.
Role of Client:-
a) Client downloads a file
b) Client should buffer the file before writing to disk( <= 100kb) I.e. buffer 100KB and write to disk then repeat this till 1MB
I wrote the code to transfer the file from Server to Client but there seem to have some issues with the program. Server starts sending the data but its lost in the transaction. Also the content of file to be transferred is erased. As I couldn't see any specific error on console so I couldn't figure out the bug. If anyone guide me whether this approach is correct or if not, please suggest proper changes.
*Server*
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
int sizeBuffer = 0;
try{
try {
serverSocket = new ServerSocket(55555);
} catch (IOException ex) {
System.out.println("Error: Unable to Connect to Server ");
}
System.out.println("Created Socket");
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Error: Unable to connect to client ");
}
System.out.println("Accepted Client Connection ");
try {
inputStream = socket.getInputStream();
sizeBuffer = socket.getReceiveBufferSize();
System.out.println("Size of Buffer " + sizeBuffer);
} catch (IOException ex) {
System.out.println("Error: unable to ger socket input stream ");
}
try {
fileOutputStream = new FileOutputStream("D:/ServerFile.txt");
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[sizeBuffer];
int count;
while ((count = inputStream.read(bytes)) > 0) {
bufferedOutputStream.write(bytes, 0, count);
}
System.out.println("Done");
}// end of first try
finally{
bufferedOutputStream.flush();
bufferedOutputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
}
And here is client side code !
*Client*
public class Client {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOuptputStream = null;
Socket socket = null;
int count;
try{
try {
socket = new Socket("127.0.0.1", 55555);
} catch (IOException ex) {
System.out.println("Error: Unable to create Socket ");
}
File file = new File("D:/ClientFile.txt");
long fileLength = file.length();
System.out.println(fileLength);
if ( Integer.MAX_VALUE < fileLength ) {
System.out.println("Error: Exceeded the size of transfer");
}
byte[] bytes = new byte[(int) fileLength];
try{
fileInputStream = new FileInputStream(file);
}catch (IOException ex){
System.out.println("Error: Unable to open fileInputStream");
}
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOuptputStream = new BufferedOutputStream(socket.getOutputStream());
while ((count = bufferedInputStream.read(bytes)) > 0) {
bufferedOuptputStream.write(bytes, 0, count);
}
}
finally{
bufferedOuptputStream.flush();
bufferedOuptputStream.close();
fileInputStream.close();
bufferedInputStream.close();
socket.close();
}
}
}
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();
}
}