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
Related
This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 6 years ago.
I am doing a sample client-server socket project where the server sends a file to the client and the client saves it in a destination folder. It works well BUT it only works ONCE. I have to restart the server and reconnect the client in order to send another file.
What am I doing wrong?
Server:
public void doConnect() {
try {
InetAddress addr = InetAddress.getByName(currentIPaddress);
serverSocket = new ServerSocket(4445, 50, addr);
isServerStarted = true;
socket = serverSocket.accept();
inputStream = new ObjectInputStream(socket.getInputStream());
outputStream = new ObjectOutputStream(socket.getOutputStream());
String command = inputStream.readUTF();
this.statusBox.setText("Received message from Client: " + command);
} catch (IOException e) {
e.printStackTrace();
}
}
Method that I use to send the file from server
public void sendFile() {
fileEvent = new FileEvent();
String fileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1, sourceFilePath.length());
String path = sourceFilePath.substring(0, sourceFilePath.lastIndexOf("/") + 1);
fileEvent.setDestinationDirectory(destinationPath);
fileEvent.setFilename(fileName);
fileEvent.setSourceDirectory(sourceFilePath);
File file = new File(sourceFilePath);
if (file.isFile()) {
try {
DataInputStream diStream = new DataInputStream(new FileInputStream(file));
long len = (int) file.length();
byte[] fileBytes = new byte[(int) len];
int read = 0;
int numRead = 0;
while (read < fileBytes.length && (numRead = diStream.read(fileBytes, read, fileBytes.length - read)) >= 0) {
read = read + numRead;
}
fileEvent.setFileSize(len);
fileEvent.setFileData(fileBytes);
fileEvent.setStatus("Success");
} catch (Exception e) {
e.printStackTrace();
fileEvent.setStatus("Error");
}
} else {
System.out.println("path specified is not pointing to a file");
fileEvent.setStatus("Error");
}
//Now writing the FileEvent object to socket
try {
outputStream.writeUTF("newfile");
outputStream.flush();
outputStream.writeObject(fileEvent);
String result = inputStream.readUTF();
System.out.println("client says: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
Client
public void connect() {
int retryCount = 0;
while (!isConnected) {
if (retryCount < 5) {
try {
socket = new Socket(currentIPAddress, currentPort);
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
isConnected = true;
//connection success
String command = inputStream.readUTF();
if (command.equals("newfile")) {
this.clientCmdStatus.setText("Received a file from Server");
outputStream.writeUTF("Thanks Server! Client Received the file");
outputStream.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
new Thread(new DownloadingThread()).start();
}
} catch (IOException e) {
e.printStackTrace();
retryCount++;
}
} else {
//Timed out. Make sure Server is running & Retry
retryCount = 0;
break;
}
}
}
Code used for downloading file in client
public void downloadFile() {
try {
fileEvent = (FileEvent) inputStream.readObject();
if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
System.out.println("Error occurred ..So exiting");
System.exit(0);
}
String outputFile = destinationPath + fileEvent.getFilename();
if (!new File(destinationPath).exists()) {
new File(destinationPath).mkdirs();
}
dstFile = new File(outputFile);
fileOutputStream = new FileOutputStream(dstFile);
fileOutputStream.write(fileEvent.getFileData());
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("Output file : " + outputFile + " is successfully saved ");
serverResponsesBox.setText("File received from server: " + fileEvent.getFilename());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
In order to get the server accept another (and more) connections, you have to put it into a loop
while(someConditionIndicatingYourServerShouldRun) {
Socker socket = serverSocket.accept();
//respond to the client
}
I'd recommend using a thread pool and submit the processing to the thread pool, i.e. by using an ExecutorService. Further, you should close Resources such as stream when finished, the "try-with-resources" construct helps you with that. So your code might look like this
ServerSocket serverSocket = ...;
ExecutorService threadPool = Executors.newFixedThreadPool(10);
AtomicBoolean running = new AtomicBoolean(true);
while(running.get()) {
Socket socket = serverSocket.accept();
threadPool.submit(() -> {
try(ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
OutputStream os = new ObjectOutputStream(socket.getOutputStream())) {
String command = is.readUTF();
if("shutdown".equals(command)) {
running.set(false);
} else {
this.statusBox.setText("Received message from Client: " + command);
}
} catch (IOException e) {
e.printStackTrace();
}
});
}
Socket's methods do not appear to function in the way their names or documentation suggest. For example. I create a client socket to connect a remote serversocket. When the connection establishes, the serversocket.accept() method returns a corresponding socket which to getinputstream from the client socket. But the problem is, if I close the client socket, the socket on the server still returns false for the isClosed() method; and, more absurdly, the Socket's InputStream on the server starts to continuously return value and no longer blocks when the client socket has closed and sending no output to the server. Below is my code:
Client code:
public class MainActivity extends AppCompatActivity {
private Button startButton, stopButton;
public byte[] buffer;
public Socket socket;
public Socket tempSocket;
private int port = 50005;
InetSocketAddress address;
private int r_port = 50006;
AudioRecord recorder;
AudioTrack audioTrack;
private int sampleRate = 16000; // 44100 for music
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
public static boolean s_status = true;
public static boolean r_status = true;
Thread r_Thread;
Thread s_Thread;
private boolean isPlay = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button) findViewById(R.id.start_button);
startButton.setOnTouchListener(talkListener);
if (socket == null) {
socket = new Socket();
address = new InetSocketAddress("192.168.0.2", port);
try {
socket.setReuseAddress(true);
System.out.println("connecting-");
} catch (IOException e) {
e.printStackTrace();
}
}
}
private final View.OnTouchListener talkListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startButton.setBackgroundColor(Color.parseColor("#0670c0"));
try {
startStreamings();
} catch (Exception e) {
e.printStackTrace();
}
return true; // if you want to handle the touch event
case MotionEvent.ACTION_UP:
startButton.setBackgroundColor(Color.parseColor("#353535"));
try {
s_status = false;
} catch (Exception e) {
e.printStackTrace();
return true; // if you want to handle the touch event
}
}
return false;
}
};
public void startStreamings(){
s_status=true;
buffer = new byte[minBufSize];
s_Thread = new Thread(new Runnable() {
#Override
public void run() {
if (socket == null) {
try {
socket = new Socket();
socket.setReuseAddress(true);
} catch (IOException e) {
e.printStackTrace();
}
}
if (!socket.isConnected()) {
try {
socket.connect(address);
System.out.println("create new connection in startStreaming");
} catch (IOException e) {
e.printStackTrace();
}
}
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, minBufSize * 10);
try {
if (s_status == true) {
recorder.startRecording();
}
} catch (IllegalStateException e) {
e.printStackTrace();
return;
}
OutputStream os = null;
while (s_status == true) {
//reading data from MIC into buffer
recorder.read(buffer, 0, buffer.length);
try {
os = socket.getOutputStream();
os.write(buffer, 0, minBufSize);
} catch (Exception e) {
e.printStackTrace();
s_status = false;
}
//System.out.println("streaming out: " + buffer.length + "fff" + c++);
}
if (recorder != null) {
recorder.stop();
recorder.release();
recorder = null;
}
}
});
s_Thread.start();
}
}
Server code:
public TcpServerSocket(){
}
public static void main(String args[]) throws Exception {
ServerSocket serverSocket = new ServerSocket(port);
sockets = new ArrayList<Socket>();
while(isListenning){
Socket socket = serverSocket.accept();
isMatched = false;
for(int i =0;i<sockets.size();i++){
Socket preSocket = sockets.get(i);
if(preSocket.getInetAddress().equals(socket.getInetAddress())){
sockets.remove(preSocket);
sockets.add(socket);
isMatched = true;
}
}
if(!isMatched){
sockets.add(socket);
socket.setKeepAlive(false);
new Thread(new TcpServerSocket(socket)).start();
System.out.println("new Connection");
}
}
serverSocket.close();
}
#Override
public void run() {
byte[] receiveData = new byte[1280];
byte[] emptyData = new byte[1280];
InputStream baiss = null;
OutputStream os;
while (isRunning){
try {
baiss = csocket.getInputStream();
if(csocket.isClosed()||!csocket.isConnected()){
isRunning = false;
sockets.remove(csocket);
System.out.println("socket closed!");
}
int numOfBytes = baiss.read(receiveData);
if(numOfBytes==-1){
isRunning=false;
sockets.remove(csocket);
csocket.close();
System.out.println("socket closed!");
}
} catch (IOException e) {
sockets.remove(csocket);
System.out.println("socket closed!");
e.printStackTrace();
}
int socketsLen = sockets.size();
for(int i = 0;i<socketsLen;i++){
Socket client = sockets.get(i);
if(!client.getInetAddress().equals(csocket.getInetAddress())){
try {
os = client.getOutputStream();
os.write(receiveData,0,1280);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(!client.equals(csocket)){
csocket = client;
System.out.println("switched!");
}
}
System.out.println(csocket.getInetAddress().toString()+"fff"+socketsLen);
}
try {
baiss.close();
csocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Can you guys give me any suggestions to close the client socket perfectly so I won't keep getting input after I close the client? Any help is much appreciated!
socket.getInputStream() still get data after I closed the other side socket
That could be because there was still data in transit that hadn't been read yet. Closing a connection doesn't abort pending data transfers. But as it turns out, it doesn't get data at all. There is simply a bug in your code.
I am really upset with socket in recent days.
I suggest you get over being upset and adopt a rational attitude towards your chosen profession.
I find socket's methods just do not function in the way their names or documentations suggest.
Let's see.
For example. I create a client socket to connect a remote serversocket. When the connection establishes,the serversocket.accept() method returns a corresponding socket which to getinputstream from the client socket. But the problem is, if I close the client socket, the socket on the server still returns true for the isClosed() method
No it doesn't. It returns false. The server's socket is still open. The client's socket is closed, and so is the connection, but isClosed() tells you about the state of the socket it is called on, not anything else, and specifically not the connection.
and more absurd, the socket.getInputStream() on the server starts to continuously return value and no longer blocks when the client socket has closed and sending no outputstream to the server.
Only if there was data in flight before the peer closed. Otherwise it is due to a bug in your code, and here it is:
//reading data from MIC into buffer
recorder.read(buffer, 0, buffer.length);
read() returns -1 at end of stream, and you are ignoring it. That's why you get a continous loop. The correct way to write this code is as follows:
int count = recorder.read(buffer, 0, buffer.length);
if (count == -1) {
recorder.close();
socket.close();
break;
}
try {
os = socket.getOutputStream();
os.write(buffer, 0, count);
You have a similar problem with your client code. You just don't seem to care about end of stream:
baiss = csocket.getInputStream();
if(csocket.isClosed()||!csocket.isConnected()){
isRunning = false;
sockets.remove(csocket);
System.out.println("socket closed!");
}
baiss.read(receiveData);
// ...
os = client.getOutputStream();
os.write(receiveData,0,1280);
The correct way to write this is as follows:
baiss = csocket.getInputStream();
int count = baiss.read(receiveData);
if(count == -1){
isRunning = false;
sockets.remove(csocket);
System.out.println("socket closed!");
}
// ...
os = client.getOutputStream();
os.write(receiveData, 0, count);
Can you guys give me any suggestions to close the client socket perfectly so I won't keep getting input after I close the client?
You are closing it perfectly. The problem is that you aren't detecting it correctly at the other end.
Well, I want to write a simple java client-server-programme, which exchanges byte arrays over tcp-sockets.
/* Server */
public class Server {
private ServerSocket Server = null;
private Socket Client = null;
public static void main(String[] args) {
Server A = new Server();
A.runServer();
A.listenServer();
}
public void runServer() {
try {
Server = new ServerSocket(1234);
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
System.exit(-1);
}
}
public void listenServer() {
try {
while (true) {
System.out.println("Waiting...");
Client = Server.accept();
System.out.println("Got something new");
readMessage(Client);
}
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
}
public byte [] readMessage (Socket socket) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1];
int len = -1;
while((len = socket.getInputStream().read(buf))!=-1){
baos.write(buf, 0, len);
}
for (int i=0; i<baos.toByteArray().length; i++) {
System.out.println(baos.toByteArray()[i]);
}
return baos.toByteArray();
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
return null;
}
public void writeMessage (Socket socket, String Message) {
try {
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
printWriter.print(Message);
printWriter.flush();
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
}
}
/* Client */
public class Client {
public static void main(String[] args) {
Client B = new Client();
B.runClient();
}
public void runClient () {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 1234);
}
catch (Exception e) {
System.out.println("Client fault: "+e.getMessage());
}
byte [] Tmp = new byte[10];
for (int i=0; i<Tmp.length; i++) {
Tmp[i] = 1;
}
writeMessage(socket, Tmp);
for (int i=0; i<10; i++) {
byte [] Message = readMessage(socket);
System.out.println(Message);
}
}
public void writeMessage (Socket socket, byte [] myByteMessage) {
try {
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.write(myByteMessage, 0, myByteMessage.length);
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
printWriter.print(myByteMessage);
printWriter.flush();
}
catch (Exception e) {
System.out.println("Could not send data over TCP");
return;
}
}
public byte [] readMessage (Socket socket) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1];
int len = -1;
while((len = socket.getInputStream().read(buf))!=-1){
baos.write(buf, 0, len);
}
for (int i=0; i<baos.toByteArray().length; i++) {
System.out.println(baos.toByteArray()[i]);
}
System.out.println("Test");
return baos.toByteArray();
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
return null;
}
}
The problem is, that the client send something to the server but the server doesn't receive anything, so he hangs at the readMessage function.
On the other hand, the client receive some weird stuff, but not the response from the server.
The server receives bytes, but it never leaves the while loop because read() never returns -1. read() returns -1 when the end of the stream is reached. And that happens only when the client closes the socket output stream. Since the client never closes the output stream, the server keeps waiting for the more bytes to come.
Side note: your code is hard to read because you don't respect the standard Java naming conventions: variables start with a lowercase letter.
I want sends and receive an object and file the order is
client -> server by ObjectOut(In)putStream
client -> server String(file name) by DataIn(Out)putStrean writeUTF
client -> server by BufferedIn(Out)putStream
server -> client by ObjectOut(In)putStream
but when the code reaches on 3 writing file takes forever (I think...it is waiting) the critical code is
byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
bos.write(data, 0, length);
System.out.println(length);
}
bis(BufferedInputStream).read() do not proceed when I print the length the output is
4096
4096
879
then just wait...
is there anyone who knows what is the problem or solution?
Server thread
public void run() {
System.out.println("\n New FileUploadServer thread started");
msg = (Message) objComm.recvObject(clientSocket);
System.out.println("server get message");
if (checkState(msg.getState()))
System.out.println(clientAddr + " session over");
System.out.println("");
}
private boolean checkState(int _state) {
switch (_state) {
case ST_EXCEL_FILE:
return receiveExcel();
default:
return false;
}
}
private boolean receiveExcel() {
Message sendMsg = receiveStr();
System.out.println("receiveStr() success");
BufferedInputStream bis;
DataOutputStream dos;
DataInputStream dis;
FileOutputStream fos;
BufferedOutputStream bos;
VoteInfo sendVoteInfo = (VoteInfo) msg.getObj();
try {
dis = new DataInputStream(clientSocket.getInputStream());
dos = new DataOutputStream(clientSocket.getOutputStream());
// check file name extension is "xls" or "xlsx"
String fName = dis.readUTF();
int idx = fName.lastIndexOf(".");
String extension = fName.substring(idx + 1, fName.length());
if (!excelFileCheck(extension))
return false;
dos.writeUTF("read_ok");
dos.flush();
System.out.println("File name: " + fName);
File f = new File(EXCEL_FILE_DIR + fName);
fos = new FileOutputStream(f);
bos = new BufferedOutputStream(fos);
bis = new BufferedInputStream(clientSocket.getInputStream());
int length;
byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
bos.write(data, 0, length);
System.out.println(length);
}
bos.flush();
// send success message to web server
System.out.println("kangji2");
objComm.sendObject(sendMsg, clientSocket);
System.out.println("File receive success!");
if (!dataToDB.excelToDB(EXCEL_FILE_DIR + fName, extension)) {
//delete all db related to this excel file here
return false;
} else {
}
bos.close();
fos.close();
dis.close();
clientSocket.close();
// send candidates information to DB server
return makeResult(sendVoteInfo);
} catch (IOException e) {
System.out.println("ReceiveExcel error");
e.printStackTrace();
}
return false;
}
public class ObjectComm {
private Message receiveMsg = null;
private ObjectOutputStream out = null;
private ObjectInputStream in = null;
public Message commObject(Message _sendMsg, Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return null;
}
try {
out = new ObjectOutputStream(_clntSocket.getOutputStream());
out.writeObject(_sendMsg);
out.flush();
System.out.println("kangji1");
in = new ObjectInputStream(_clntSocket.getInputStream());
receiveMsg = (Message) in.readObject();
System.out.println("kangji2");
return receiveMsg;
} catch (Exception e) {
System.out.println("commObject err");
e.printStackTrace();
return null;
}
}
public boolean sendObject(Message _msg, Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return false;
}
try {
out = new ObjectOutputStream(_clntSocket.getOutputStream());
out.writeObject(_msg);
out.flush();
return true;
} catch (IOException e) {
System.out.println("Object comm send err");
e.printStackTrace();
return false;
}
}
public Message recvObject(Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return null;
}
try {
in = new ObjectInputStream(_clntSocket.getInputStream());
receiveMsg = (Message) in.readObject();
return receiveMsg;
} catch (Exception e) {
System.out.println("Object comm recvObject err");
e.printStackTrace();
return null;
}
}
}
Did you close the connection in client side (sender side, or wherever opposite of your input stream) ? read(byte[], int, int ) in BufferedInputStream will return when end of the stream has been reached.
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html#read(byte[],%20int,%20int)
client -> server by ObjectOut(In)putStream
client -> server String(file name) by DataIn(Out)putStrean writeUTF
client -> server by BufferedIn(Out)putStream
server -> client by ObjectOut(In)putStream
Too much stuff here.
Playing with streams at different levels of your stream stack simply does not work.
If you want to send objects, use the ObjectInput/OutputStreams for everything. Construct them as follows:
new ObjectOutputStream(new BufferedOutputStream(...))
and
new ObjectInputStream(new BufferedInputStream(...))
Send the objects with writeObject(); send the strings with writeObject() or writeUTF(); send byte arrays via ObjectOutputStream.write(); and use the complementary methods of ObjectInputStream at the other end.
I am developing one program in which a user can download a number of files. Now first I am sending the list of files to the user. So from the list user selects one file at a time and provides path where to store that file. In turn it also gives the server the path of file where does it exist.
I am following this approach because I want to give stream like experience without file size limitation.
Here is my code..
1) This is server which gets started each time I start my application
public class FileServer extends Thread {
private ServerSocket socket = null;
public FileServer() {
try {
socket = new ServerSocket(Utils.tcp_port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
try {
System.out.println("request received");
new FileThread(socket.accept()).start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
2) This thread runs for each client separately and sends the requested file to the user 8kb data at a time.
public class FileThread extends Thread {
private Socket socket;
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public FileThread(Socket socket) {
this.socket = socket;
System.out.println("server thread" + this.socket.isConnected());
//this.filePath = filePath;
}
#Override
public void run() {
// TODO Auto-generated method stub
try
{
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
try {
//************NOTE
filePath=(String) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = new File(this.filePath);
byte[] buf = new byte[8192];
InputStream is = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(is);
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
int c = 0;
while ((c = bis.read(buf, 0, buf.length)) > 0) {
oos.write(buf, 0, c);
oos.flush();
// buf=new byte[8192];
}
oos.close();
//socket.shutdownOutput();
// client.shutdownOutput();
System.out.println("stop");
// client.shutdownOutput();
ois.close();
// Thread.sleep(500);
is.close();
bis.close();
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
NOTE: here filePath represents the path of the file where it exists on the server. The client who is connecting to the server provides this path. I am managing this through sockets and I am successfully receiving this path.
3) FileReceiverThread is responsible for receiving the data from the server and constructing file from this buffer data.
public class FileReceiveThread extends Thread {
private String fileStorePath;
private String sourceFile;
private Socket socket = null;
public FileReceiveThread(String ip, int port, String fileStorePath,
String sourceFile) {
this.fileStorePath = fileStorePath;
this.sourceFile = sourceFile;
try {
socket = new Socket(ip, port);
System.out.println("receive file thread " + socket.isConnected());
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
oos.writeObject(sourceFile);
oos.flush();
// oos.close();
File f = new File(fileStorePath);
OutputStream os = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buf = new byte[8192];
int c = 0;
//************ NOTE
ObjectInputStream ois = new ObjectInputStream(
socket.getInputStream());
while ((c = ois.read(buf, 0, buf.length)) > 0) {
// ois.read(buf);
bos.write(buf, 0, c);
bos.flush();
// buf = new byte[8192];
}
ois.close();
oos.close();
//
os.close();
bos.close();
socket.close();
//Thread.sleep(500);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
NOTE : Now the problem that I am facing is at the first time when the file is requested the outcome of the program is same as my expectation. I am able to transmit any size of file at first time. Now when the second file is requested (e.g. I have sent file a,b,c,d to the user and user has received file a successfully and now he is requesting file b) the program faces deadlock at this situation. It is waiting for socket's input stream. I put breakpoint and tried to debug it but it is not going in FileThread's run method second time. I could not find out the mistake here. Basically I am making a LAN Messenger which works on LAN. I am using SWT as UI framework.
A more basic problem.
You are only processing the first socket.
while(true) {
new FileThread(socket.accept()).start();
}
As per the suggestion of Peter Lawrey i removed all the redundant streams code from my source code. Now the changed source code is as follows and the problem remains.
1) No change in FileServer. It is as it is .
2) FileThread
public class FileThread extends Thread {
private Socket socket;
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public FileThread(Socket socket) {
this.socket = socket;
System.out.println("server thread" + this.socket.isConnected());
// this.filePath = filePath;
}
#Override
public void run() {
// TODO Auto-generated method stub
try
{
OutputStream oos = socket.getOutputStream();
oos.flush();
InputStream ois = socket.getInputStream();
byte[] buf = new byte[8192];
ois.read(buf);
filePath = new String(buf);
System.out.println(filePath);
File f = new File(this.filePath);
InputStream is = new FileInputStream(f);
int c = 0;
while ((c = is.read(buf, 0, buf.length)) > 0) {
oos.write(buf, 0, c);
oos.flush();
}
oos.close();
System.out.println("stop");
ois.close();
is.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
3) FileReceiverThread
public class FileReceiveThread extends Thread {
private String fileStorePath;
private String sourceFile;
private Socket socket = null;
public FileReceiveThread(String ip, int port, String fileStorePath,
String sourceFile) {
this.fileStorePath = fileStorePath;
this.sourceFile = sourceFile;
try {
socket = new Socket(ip, port);
System.out.println("receive file thread " + socket.isConnected());
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
try {
OutputStream oos = socket.getOutputStream();
oos.write(sourceFile.getBytes());
oos.flush();
File f = new File(fileStorePath);
OutputStream os = new FileOutputStream(f);
byte[] buf = new byte[8192];
int c = 0;
// ************ NOTE
InputStream ois = socket.getInputStream();
while ((c = ois.read(buf, 0, buf.length)) > 0) {
os.write(buf, 0, c);
os.flush();
}
ois.close();
oos.close();
os.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
is there still something which i am missing ?