I am making a program which takes a file, and sends it via socket to client. Client receives it and saves it to a file. That is what it is supposed to do.
But somehow, byte array which client receives, contains only 0 bytes, so my output file is empty. here is the code:
Server:
try {
serverSocket=new ServerSocket(7575);
serverSocket.setSoTimeout(1000000);
System.out.println("serverSocket created.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Error in creating new serverSocket on port 7575");
}
for(int i=0;i<array.length;i++)
System.out.println(array[i]);
Socket socket=null;
try {
System.out.println("Waiting for client...");
socket=serverSocket.accept();
System.out.println("Client accepted.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
PrintWriter outWriter=null;
DataOutputStream outputStream=null;
OutputStream os=null;
BufferedOutputStream bos=null;
try {
os=socket.getOutputStream();
outputStream=new DataOutputStream(os);
outWriter=new PrintWriter(socket.getOutputStream());
bos=new BufferedOutputStream(socket.getOutputStream());
System.out.println("Server streams created.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("sending name "+name);
outWriter.println(name);
outWriter.flush();
outWriter.println(array.length);
outWriter.println("array.length"+array.length);
outWriter.flush();
try {
os.write(array);
os.flush();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("couldnt send array of bytes");
}
try {
os.close();
outputStream.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
client:
public class Client implements Runnable {
private Socket socket;
private String folderPath;
public Client(String p)
{
folderPath=p;
}
#Override
public void run()
{
try {
System.out.println("Client connecting to localhost on 7575 port...");
socket=new Socket("localhost", 7575);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader reader=null;
BufferedInputStream bis=null;
InputStream input=null;
DataInputStream in=null;
try {
System.out.println("creating streams");
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
input=socket.getInputStream();
in=new DataInputStream(input);
bis=new BufferedInputStream(socket.getInputStream());
System.out.println("streams created!");
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
String name="";
int size=0;
String s="32";
try {
name=reader.readLine();
s=reader.readLine();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
if(s!=null)
size=Integer.parseInt(s);
System.out.println("name: "+name);
System.out.println("size: "+size);
byte [] arr=new byte[size];
try {
input.read(arr);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("couldnt read the byte array");
}
for(int i=0;i<arr.length;i++)
System.out.println(arr[i]);
FileOutputStream fos=null;
try {
fos=new FileOutputStream(folderPath+"/"+name);
} catch (FileNotFoundException ex) {
System.out.println("Could write the file");
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos.write(arr);
fos.flush();
} catch (IOException ex) {
System.out.println("Could write the file2");
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
in.close();
input.close();
reader.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Mixing binary and text modes on the same stream is tricky. You would be advised not to do it. Using DataInputStream (for the name, count and file content) is one possible solution. (And that is what I would try). Another would be to encode the file content as text (e.g. using Base64 encoding).
The problem with your current "mixed stream: code is on the client side. When you read the name and size from the BufferedReader, you will cause the reader to read and buffer up to 4096 bytes from the socket. The problem is that some of those bytes are file content. So when you then try to read the content from the underlying InputStream here:
input.read(arr);
you may find that there is nothing left to read. Result: an empty or corrupted file.
There's another problem too. Your code assumes that the input.read(arr) statement is going to read the rest of the stream, or until it fills the byte array. This assumption is incorrect. When you are reading from a socket stream, the read is liable to return only the bytes that are currently available (in the client-side network stack).
Once again, the result is liable to be a corrupted file. (In this case truncated.)
The read code should look something like this:
int count = 0;
while (count < size) {
int bytesRead = is.read(bytes, count, bytes.length - count);
if (bytesRead == -1) {
throw EOFException("didn't get a complete file");
}
count += bytesRead;
}
Finally:
Reading the file content into byte arrays at both ends wastes memory, and is going to be problematic for a really large file.
You really should be using "try with resources" to ensure that the streams are all closed properly. Doing it by hand is cumbersome, and risks resource leaks.
you can use DataOutputStream to directly write some string(message) on output stream using writeUTF() function. And then u can receive your message using object of DataInputStream class by using readUTF() method.
u can send data using following:-
String message="something";
DataOutputStream out=new DataOutputStream(socket.getOutputStream());
out.writeUTF(message);
and u can receive data or message using following:-
DataInputStream in=new DataInputStream(socket.getInputStream());
String message=in.readUTF();
i basically used these method to read data from input stream and write data to outputstream many times and it worked every time, so u should check this way too.
I am making a program which takes a file, and sends it via socket to client. Client receives it and saves it to a file. That is what it is supposed to do.
If you have no need to inspect the content of what is being passed through, then straight InputStream and OutputStream are the way to go, in my opinion. The code is straightforward and fast as it avoids any overhead imposed by higher-level stream types that inspect the content for encoding, etc. This also reduces the opportunity for corrupting the information.
I agree with Stephen C's answer except for
Reading the file content into byte arrays at both ends wastes memory, and is going to be problematic for a really large file.
With the specific requirement to simply move one file to another system with no need to look at the values, this isn't an issue if you know how to handle the content. The basic flow is
client: InputStream in = getFileInputStream();
OutputStream out = socket.getOutputStream();
byte[] bytes = new byte[BUFFER_SIZE]; // could be anything
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
in.close();
out.close();
server: InputStream in = socket.getInputStream();
OutputStream out = getFileOutputStream();
// the rest is the exact same thing as the client
This will handle any arbitrarily sized file, limited only by disk size of the server.
Here is an example I whipped up. It's admittedly hacky (the use of the FILE_COUNTER and STOP_KEY for example) but I'm only attempting to show various aspects of having a user enter a file and then send it between a client and server.
public class FileSenderDemo {
private static final int PORT = 7999;
private static final String STOP_KEY = "server.stop";
private static final int[] FILE_COUNTER = {0};
public static void main(String[] args) {
FileSenderDemo sender = new FileSenderDemo();
Thread client = new Thread(sender.getClient());
Thread server = new Thread(sender.getServer());
server.start();
client.start();
try {
server.join();
client.join();
} catch (InterruptedException e) {
FILE_COUNTER[0] = 999 ;
System.setProperty(STOP_KEY,"stop");
throw new IllegalStateException(e);
}
}
public void send(File f, OutputStream out) throws IOException{
try(BufferedInputStream in = new BufferedInputStream(new FileInputStream(f),1<<11)){
byte[] bytes = new byte[1<<11];
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
}
}
public Runnable getClient() {
return () -> {
while(FILE_COUNTER[0] < 3 && System.getProperty(STOP_KEY) == null) {
Socket socket;
try {
socket = new Socket("localhost", PORT);
} catch (IOException e) {
throw new IllegalStateException("CLIENT: Can't create the client: " + e.getMessage(), e);
}
File f = getFile();
try (BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream())) {
send(f, out);
} catch (IOException e) {
System.out.println("CLIENT: Failed to send file " + f.getAbsolutePath()+" due to: " + e.getMessage());
e.printStackTrace(System.err);
} finally {
FILE_COUNTER[0]++;
}
}
System.setProperty(STOP_KEY,"stop");
};
}
public File getFile(){
Scanner scanner = new Scanner(System.in);
System.out.println("CLIENT: Enter a file Name: ");
return new File(scanner.next());
}
public Runnable getServer(){
return () -> {
OutputStream out = null;
try{
ServerSocket server = new ServerSocket(PORT);
server.setSoTimeout(20000);
while(System.getProperty(STOP_KEY) == null){
Socket socket = null;
try {
socket = server.accept();
}catch (SocketTimeoutException e){
System.out.println("SERVER: Waited 20 seconds for an accept. Now checking if we need to stop.");
continue;
}
String fileName = "receivedFile_"+System.currentTimeMillis()+".content";
File outFile = new File(fileName);
out = new BufferedOutputStream(new FileOutputStream(outFile));
InputStream in = socket.getInputStream();
int bytesRead;
byte[] bytes = new byte[1<<12];
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
out.close();
socket.close();
System.out.println("SERVER: Just created a new file: " + outFile.getAbsolutePath());
}
System.out.println("SERVER: " + STOP_KEY + " was not null, so quit.");
}catch (IOException e){
throw new IllegalStateException("SERVER: failed to receive the file content",e);
}finally {
if(out != null){
try{out.close();}catch (IOException e){}
}
}
};
}
}
Related
I have created a simple utility, that implements server and client. Server waits for incomming connection, client connects and if there are any files in folder on server - they are sending to client.
I used DataInput/OutputStreams - writeUTF/readUTF for sending messages between client and server, writeLong/readLong - to send file size, write/read to send data.
The problem is that when I run both client and server - working stucks after sending one or two files. But if I trace the client and server in IDE step-by-step it works great, and it also works if I transfer files with buffer size in one byte - so it works really slowly, but it does not stuck.
I use Eclipse IDE, jdk 1.7 on client side and 1.8 on server side (tried 1.7 also), Ubuntu linux and Windows 2003 Server on two instances of VMWare players.
I also tried to add Thread.sleep(10000) and flush() anything might be flushed, even added socket.setTcpNoDelay(true); but no result.
It looks like server sends the next file name and waits for echo() from client, but client does not get it and stucks on readUTF(). But, if I do it in manual mode step-by-step it works fine.
Any ideas? Thank you!
Client source:
/**
* Method receives a file from server
* #param outWriter
* #param inBufferedReader
* #param inStream
*
*/
private void receiveFileFromServer(DataOutputStream out, DataInputStream in) {
try {
String fileName = in.readUTF(); ///<----- stucks here *************
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("Receiving file "+fileName);
}
out.writeUTF(fileName);
out.flush();
Long fileSize = in.readLong();
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("Filesize "+fileSize);
}
out.writeUTF(fileSize.toString());
out.flush();
File localFile = new File(fileName);
FileOutputStream fileOS = new FileOutputStream(localFile);
byte[] buffer = new byte [2048];
int bytesRead = 0;
try {
for (int i = 0; i<fileSize/buffer.length; i++) {
bytesRead = in.read(buffer, 0, buffer.length);
fileOS.write(buffer,0, bytesRead);
}
bytesRead = in.read(buffer, 0, (int)(fileSize%buffer.length));
fileOS.write(buffer,0, bytesRead);
System.out.println("----------------------- "+bytesRead);
} catch (IOException e) {
awlConnectionLogger.error("Error reading file "+fileName);
};
fileOS.close();
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("File received.");
}
} catch (IOException e) {
awlConnectionLogger.error("Error reading Stream or socket closed");
}
}
/**
* Method sends a #param command to server, waits for answer, then if answer is not null and equals #param answer it logs #param messageOk else #param messageError
* returns true if everything is ok, else returns false
* #param outWriter
* #param inBufferedReader
* #throws IOException
*/
private boolean sendCommandReceiveAnswer(String command, String answer, String messageOk,String messageError,
DataOutputStream out, DataInputStream in) throws IOException {
out.writeUTF(command); //Hello handshake
out.flush();
String data = in.readUTF();
if ((data!=null)&&(data.equals(answer))) {
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info(messageOk);
}
return true;
} else {
awlConnectionLogger.error(messageError);
return false;
}
}
/**
* Try to establish connection with the awl-server according to detected RDP session
* #param serverIP - ip address of server
* #param user - username
*/
private void establishConnection(String serverIP, String user) {
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("Trying to establish awl-connection to "+serverIP+" as "+user);
}
Integer remoteAwlPort = Integer.parseInt(Config.awlPort);
try (Socket awlServerSocket = new Socket(serverIP,remoteAwlPort)) {//Creating autocloseable socket
this.awlServerSocket = awlServerSocket;
DataOutputStream out = new DataOutputStream(awlServerSocket.getOutputStream());
DataInputStream in = new DataInputStream(awlServerSocket.getInputStream());
if (!sendCommandReceiveAnswer("Hello-awl-client", "Hello-awl-server", "Server hello OK.",
"Unknown server type. Closing thread.", out, in)) {
return;
}; //Hello handshake - return if not successful
if (!sendCommandReceiveAnswer(user, "User-ok", "Username sent.", "Error sending username. Closing thread.", out, in)) {
return;
} //Sending username
String hostName = InetAddress.getLocalHost().getHostName(); //Getting client local hostname
if (!sendCommandReceiveAnswer(hostName, "Hostname-ok", "Local hostname "+hostName+" sent. Ready to receive files.",
"Error sending hostname. Closing thread.", out, in)) {
return;
} //Sending hostname
awlServerSocket.setTcpNoDelay(true);
while (isActive) {
receiveFileFromServer(out, in); //receiving files
out.writeUTF("Ready");
out.flush();
}
} catch (UnknownHostException e) {
awlConnectionLogger.error("Error in server IP adress");
} catch (SocketException e) {
awlConnectionLogger.error("Problem accessing or creating Socket.");
} catch (IOException e) {
awlConnectionLogger.error("General IO Error or Socket closed");
};
}
Server source:
void Echo (DataInputStream in) {
String echo = null;
try {
echo = in.readUTF();
System.out.println("Echo:"+echo);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void sendToClient (File file, DataOutputStream out, DataInputStream in) {
System.out.println("Sending file name "+file.getName());
try {
out.writeUTF(file.getName());
out.flush();
Echo (in); //<--------- stucks here *******************
out.writeLong(file.length());
out.flush();
Echo (in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Sending file");
byte [] buffer = new byte [2048];
FileInputStream fileIS = null;
try {
fileIS = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.println("Error opening file "+file);
e.printStackTrace();
}
try {
Integer bytesRead;
int i = 0;
while((bytesRead=fileIS.read(buffer))>0) {
out.write(buffer, 0, bytesRead);
}
out.flush();
} catch (IOException e) {
System.out.println("Error reading file "+file);
e.printStackTrace();
};
System.out.println("File sent.");
try {
fileIS.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run () {
DataOutputStream out = null;
DataInputStream in = null;
String data = null;
String user = null;
String clientHostName = null;
try {
socket.setTcpNoDelay(true);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("New incoming connection thread starded.");
try {
data = in.readUTF();
if (data.equals("Hello-awl-client")) {
System.out.println("Client hello OK.");
out.writeUTF("Hello-awl-server");
out.flush();
user = in.readUTF();
System.out.println("User: "+user);
out.writeUTF("User-ok");
out.flush();
clientHostName = in.readUTF();
System.out.println("Client hostname: "+clientHostName);
System.out.println("Server hostname: "+InetAddress.getLocalHost().getHostName());
out.writeUTF("Hostname-ok");
out.flush();
System.out.println("Ready to send files.");
while (isActive) {
File file = new File(ServerConfig.pdfFolder+"//"+user);
if (!file.isDirectory()) {
System.out.println("Error in path to user directory. Exiting thread");
return;
}
File [] files = file.listFiles();
for (File fileItem:files) {
while (!fileItem.renameTo(fileItem)) {
Thread.sleep(1000);
}; //waits while file is not busy to send it
if (socket.isOutputShutdown()) {
out = new DataOutputStream(socket.getOutputStream());
}
sendToClient (fileItem, out, in);
if (fileItem.delete()) {
System.out.println("File deleted.");
} else {
System.out.println("File not deleted.");
}
data = in.readUTF();
System.out.println(data);
}
}
} else {
System.out.println("Unknown connection type. Closing thread.");
return;
}
} catch (IOException | InterruptedException e) {
System.out.println("Connection error or can't sleep thread. Closing thread.");
return;
}
}
In school we have a project where we have to send a file from server to a client. The problem we have is that when we transfer the file from the server to the client, the server shutsdown the connection. Here is our code so far:
Client:
public static void main(String argv[]) throws Exception {
int port = 8888; //default
if (argv.length
> 0) {
port = Integer.parseInt(argv[0]);
}
Socket clientSocket = new Socket("127.0.0.1", port);
PrintStream outToServer = new PrintStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
File f = new File("dictionaryPart.txt");
String serverCommand = inFromServer.readLine().toLowerCase();
while (serverCommand != null) {
System.out.println(serverCommand);
switch (serverCommand) {
case "velkommen":
outToServer.println("Hej");
break;
case "file":
f = copy(clientSocket, f);
String matches = CrackerCentralized.checkFile(f);
System.out.println(matches);
outToServer.println(matches);
break;
}
serverCommand = inFromServer.readLine().toLowerCase();
}
}
public static File copy(Socket clientSocket, File f) {
try {
int filesize = 2022386;
int bytesRead;
int currentTot = 0;
byte[] buffer = new byte[filesize];
InputStream is = clientSocket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(buffer, 0, buffer.length);
currentTot = bytesRead;
while (bytesRead != -1) {
bytesRead = is.read(buffer, currentTot, (buffer.length - currentTot));
if (bytesRead >= 0) {
currentTot += bytesRead;
}
}
bos.write(buffer, 0, currentTot);
bos.flush();
bos.close();
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
return f;
}
Server:
try {
PrintStream outToClient = new PrintStream(connection.getOutputStream());
OutputStream os = connection.getOutputStream();
BufferedInputStream input = new BufferedInputStream(new FileInputStream(f));
outToClient.println("file");
final byte[] buffer = new byte[(int) f.length()];
input.read(buffer, 0, buffer.length);
os.write(buffer, 0, buffer.length);
os.write(-1);
os.flush();
System.out.println(connection.isClosed());
os.close();
System.out.println(connection.isClosed());
} catch (IOException ex) {
Logger.getLogger(SocketController.class.getName()).log(Level.SEVERE, null, ex);
}
I am aware of WHY the connection keeps on closing. We close the socket's output by writing
output.close();
But I don't know in what other way we must try to do this to make the server keep listening for the clients answer (match/no match), so that the server knows wether it should send more files or if the client was successful.. Is it even possible to send at file without shutting down the connection to the server? I've googled all day the last 2 days without any luck
Thanks for reading and for your help.
In order to implement what you are asking, you need to establish a communication protocol that the server and client understand. Something needs to be transmitted that says, "I'm starting to send information to you," and something that says, "I'm done sending stuff." There could be more -- such as information delimiting (e.g. Mime multipart form boundary). But at a minimum, you need the start and stop tokens.
Expanding on that: Look at the code in its simplest form: server:loop{write()} -> client:loop{read()}. Closing the stream on the server-side sends the -1 value to the client, which is usually consumed as the stop signal. If you want to maintain the connection indefinitely, and write to the client at different times, something has to be sent that says, "This transaction is complete". The following is pseudo-ish code -- freehand, not compiled.
// SERVER
private Socket socket; // initialized somewhere
private static final byte[] STOP = "</COMMS>".getBytes();
public void sendData(byte[] bytes) throws IOException{
OutputStream out = socket.getOutputStream();
if(bytes != null){
out.write(bytes,0,bytes.length);
}
out.write(STOP);
} // notice we exit the method without closing the stream.
// CLIENT
private Socket socket; // initialized somewhere
private static final byte[] STOP = "</COMMS>".getBytes();
private static final int BUFFER_SIZE = 1024 << 8;
private InputStream in;
public byte[] receiveData(){
if(in == null){
in = socket.getInputStream();
}
byte[] content;
byte[] bytes = new byte[BUFFER_SIZE];
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){ // normal termination
if(receivedStop(bytes,bytesRead)){ // see if stopped
removeStopBytes(bytes,bytesRead); // get rid of the STOP bytes
content = buildContent(content,bytes,bytesRead); // transfer bytes to array
break;
}
content = buildContent(content,bytes,bytesRead); // transfer bytes to array
}
return content;
}
Again, that was freehand and not compiled or tested. I'm sure it's not fully correct but hopefully you get the gist. The server writes content but never closes the stream. The client reads the stream looking for the STOP content, building up the final content until the stop is reached.
Thanks to madConan for the reply, it gave me a good idea of how to do it. I will post my code here, so others can use it in future.
SERVER CODE
public void run() {
try {
PrintStream outToClient = new PrintStream(connection.getOutputStream());
OutputStream os = connection.getOutputStream();
BufferedInputStream input = new BufferedInputStream(new FileInputStream(f));
outToClient.println("file");
copy(input, os, f);
System.out.println(connection.isClosed());
} catch (IOException ex) {
Logger.getLogger(SocketController.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static void copy(final InputStream is, final OutputStream os, File f) throws IOException {
final byte[] stop = "stop".getBytes();
final byte[] buffer = new byte[(int) f.length()];
is.read(buffer, 0, buffer.length);
os.write(buffer, 0, buffer.length);
os.write(stop);
os.flush();
}
CLIENT CODE
public static File recieveData(Socket clientSocket, File f) {
try {
InputStream in = clientSocket.getInputStream();
FileOutputStream output = new FileOutputStream(f);
byte[] content;
byte[] bytes = new byte[1024 << 8];
int bytesRead;
while (true) {
if (recieveStop(f)) {
removeStop(f);
break;
}
bytesRead = in.read(bytes);
output.write(bytes, 0, bytesRead);
}
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
return f;
}
public static boolean recieveStop(File f) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
String currentLine;
String lastLine = "";
while ((currentLine = br.readLine()) != null) {
lastLine = currentLine;
}
if (lastLine.equals("stop")) {
return true;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
br.close();
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
return false;
}
public static void removeStop(File f) {
try {
RandomAccessFile raFile = new RandomAccessFile(f, "rw");
long length = raFile.length();
raFile.setLength(length - 4);
raFile.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Master_Slave_Sockets_Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
Hope this will help others with the same problem.
I am trying to record audio into a file in the server side which is an android device and send it to client, another android device when the record is done. It works fine for the first time, but when I record again, my second record is not received by the client. Here is my code
SERVER THREAD:
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
client = serverSocket.accept();
OutputStream out = client.getOutputStream();
while(true){
//record status is true
//when record is done
if(record_status){
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(mFileName)));
BufferedOutputStream bout = new BufferedOutputStream(out);
copyFile(bis, bout);
bout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
record_status = false;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
CLIENT THREAD:
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Socket socket = new Socket(serverAddr, SERVERPORT);
connected = true;
while (connected) {
try {
dis = socket.getInputStream();
while(true){
if(dis.available()>0){
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(mFileName)));
copyFile(socket.getInputStream(), bos);
bos.flush();
//file has been received
//start playing the audio
startPlaying();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
} catch (Exception e) {
connected = false;
}
}
}
method copyFile:
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[4092];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
return false;
}
return true;
}
This really should be a comment, however i don't have the rep yet. But it seems to me that on the server side you have record_status set to true on first iteration of while loop once that stream is sent to client then record_status is set false and never actually set to true again inside the while loop. As a result the code inside the if statement is never executed again. So where does record_status get set to true again? check the logcat on server side device to see if anything is actually put into bitstream for the second recording if not this is your problem
I have problem with reading from socket inputStream. But only in one method in class. Here is my code:
server:
private void copyFile(String mainPath, String path) {
outS.println("Sending file!");
outS.println(path);
outS.flush();
BufferedInputStream fis = null;
OutputStream os;
File file = new File(mainPath);
String str;
byte[] buffer = new byte[4096];
long numOfChunks = file.length() / 4096, num = 0, lng;
try {
fis = new BufferedInputStream(new FileInputStream(file));
os = socket.getOutputStream();
outS.println(numOfChunks);
fis.read(buffer, 0, 4096);
os.write(buffer, 0, buffer.length);
os.flush();
num++;
} catch (FileNotFoundException ex) {
System.out.println("<ERROR> Clerk, copyFile: File not found.");
System.out.println(ex);
} catch (IOException ex) {
System.out.println("<ERROR> Clerk, copyFile: Could not write or read file.");
System.out.println(ex);
} finally {
try {
fis.close();
} catch (IOException ex) {
Logger.getLogger(Clerk.class.getName()).log(Level.SEVERE, null, ex);
}
}
waitEnd();
}
client:
private void copyFile(String destination) {
FileOutputStream fos = null;
long numOfChunks, num = 0;
SBuffer sBuffer;
byte[] buffer = new byte[4096];
InputStream is;
try {
fos = new FileOutputStream(new File(destination));
BufferedOutputStream bos = new BufferedOutputStream(fos);
is = socket.getInputStream();
numOfChunks = Long.parseLong(inS.readLine());
System.out.println(num + "/" + numOfChunks);
int bytesRead = is.read(buffer, 0, buffer.length);
bos.write(buffer, 0, bytesRead);
num++;
} catch (FileNotFoundException ex) {
System.out.println("<ERROR> Client, copyFile: File not found.");
System.out.println(ex);
} catch (IOException ex) {
System.out.println("<ERROR> Client, copyFile: Could not write or read file.");
System.out.println(ex);
} finally {
try {
fos.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
outS.println("end");
outS.flush();
}
Let me explain few things. Everythings goes fine, but client on line int bytesRead = is.read(buffer, 0, buffer.length) will stuck, because nothing is in stream (is.available = 0 ). And i don't know why. Although i send it from server many times.
And I can't close stream, because socket will close too.
Method waitEnd() waits for string "end" in socket's input stream.
I have searched many tutorials and things on internet, but no one help.
Code which establish connection:
Server:
public void run() {
try {
ssocket = new ServerSocket(2332);
Socket socket = ssocket.accept();
clerk = new Clerk(socket, mainPath);
(new Thread(clerk)).start();
} catch (IOException ex) {
}
try {
ssocket.close();
} catch (IOException ex) {
}
}
public Clerk(Socket socket, String path) {
this.socket = socket;
mainTree = new FileTree(path);
}
public Client(String address, String[] dirs) {
try {
socket = new Socket(address, 2332);
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
Client and clerk has same method run:
#Override
public void run() {
try {
inS = new BufferedReader(iss);
outS = new PrintWriter(socket.getOutputStream(), true);
oos = new ObjectOutputStream(socket.getOutputStream());
iss = new InputStreamReader(socket.getInputStream());
ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException ex) {
}
msg();
try {
inS.close();
iss.close();
outS.close();
ois.close();
oos.close();
socket.close();
} catch (IOException ex) {
}
}
Resolved. I created second socket for file transfer only.
Hello guys I am trying to do an echo Server by java but it is nnot working .. .I don't know why .. but it seems like the server is waiting the client and the client is waiting the server ... so they can't deliver the infromation to each other ..
here is the code
for the Server
ServerSocket server = null;
try {
server = new ServerSocket(3333);
System.out.println("Listening on 3333");
} catch (IOException ex) {
System.out.println("Error can't connect to 3333");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = server.accept();
} catch (IOException ex) {
System.out.println("Accept fail");
System.exit(1);
}
PrintWriter out = null;
try {
out = new PrintWriter(clientSocket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(JavaApplication20.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(JavaApplication20.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String inputLine, outputLine;
while(!(inputLine=br.readLine()).equals("bye"))
{
out.print("echo: " + inputLine);
}
out.close();
br.close();
clientSocket.close();
server.close();
System.out.println("Server Exited");
and here is the code for the client
Socket client = null;
try {
client = new Socket("localhost", 3333);
System.out.println("Connected on 3333");
} catch (UnknownHostException ex) {
System.out.println("Couldn't connect to the server");
System.exit(1);
} catch (IOException ex) {
Logger.getLogger(KnockKnockClient.class.getName()).log(Level.SEVERE, null, ex);
}
PrintWriter out = null;
BufferedReader in = null;
BufferedReader stdIn = null;
try {
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException ex) {
Logger.getLogger(KnockKnockClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(KnockKnockClient.class.getName()).log(Level.SEVERE, null, ex);
}
stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer, fromUser;
while((fromUser=stdIn.readLine())!=null)
{
System.out.println("From user: "+ fromUser);
out.print(fromUser);
fromServer=in.readLine();
System.out.println(fromServer);
}
out.close();
stdIn.close();
in.close();
client.close();
System.out.println("client Exited");
Any Help with that ??
You're sending some string from the client ("Hello" for example), and you're trying to read it with readLine() on the server (and vice versa). readLine() will only return once it finds an EOL character, or once the input stream is closed.
Since the client doesn't send any EOL char, the server waits indefinitely, and the client also because it waits for the answer from the server.
Send "Hello\n", and it will work better.
After out.print(fromUser); use out.flush() in your client and server. flush will make sure it will right to the socket.
while((fromUser=stdIn.readLine())!=null)
{
System.out.println("From user: "+ fromUser);
out.print(fromUser);
out.flush();
fromServer=in.readLine();
System.out.println(fromServer);
}
out.close();
stdIn.close();
in.close();
client.close();
Regarding flush, Extracted from java doc.
Flushes the stream. If the stream has saved any characters from the various write() methods in a buffer, write them immediately to their intended destination. Then, if that destination is another character or byte stream, flush it. Thus one flush() invocation will flush all the buffers in a chain of Writers and OutputStreams.
If the intended destination of this stream is an abstraction provided by the underlying operating system, for example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to the operating system for writing; it does not guarantee that they are actually written to a physical device such as a disk drive.