This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
Hey everyone, i'm trying to develop a email program with client and server. The client will send the message containing the details:
1. To whom it should be send
3. Message Part
This message will go to server which in turn will redirect it to the expected destination(the one contained in the "To" part of the message)
I have written the code for both client and server which are as follows:
CLIENT code(I have written it in NetBeans):
Both the server and the client compiles fine and run too, but the problem is that: when client sends first message to the server it goes fine, server gets it and forwards it to the destination. However, when the message is sent second tym, the server does not recieve it. Thus the loop in the server program runs only once, but im not getting why so....please help.
If you check the output you will be receiving the following stack trace when you are running the client code.
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
I think most of your problems are caused by closing things you shouldnt, and once you have fixed that you may have problems closing things you should.
The main problem i see is that you is because you have closed the Socket ( line 37 of the client code), and it has not been replaced. Try removing the ssoc.close ( line36) and moving the accept and and new ObjectOutputStream into the while loop.
Although make sure you close the Input stream.
Also with your server code it appears you are not closing the "another" socket.
Joined: Dec 19, 2009
Thanks very much for your reply Steve,
I noticed the points of error you told, so i corrected them in my program.
I have made the following changes:
1)In the Client Code, i closed the socket in the while loop(line 37), removed the ssoc.close() line(line no 36), brought the accept and newObjectInputStream in to the loop,and closed the inputStream at the end of the loop.
2)In the server code, i closed the another socket,
and the socket s.close(),
input stream input.close().
and the outputstream o1.close();
But even after making these significant changes, my problem is not resolved.
The codes compile fine as before but then the following problem arises(as it did before):
I tried testing it on local machine,
i run server and then client,
after than i filled out the details in the client form, mentioning the localhost in the to field,
For the first time,Client sends succesfully, Server also recieves Successfully and forwards it to the expected destination(in this case the localmachine) Successfully, and is recieved successfully at the client(which is reflected in the recieved message details textarea)
But then when i do it for second time,Client sends succesfully, Server DOESNOT recieve it, and hence do not forward it, and hence message not received at the destination.
THE PROBLEM is that the loop in the SERVER CODE runs only once(I don't know why is this so, im really frustated).
Please help me pointing out where am i going wrong.
Just run the code(after making the changes you told) and tell me why is the loop in the SERVER code runs only once(for the first time), I think that is the CORE PROBLEM........
Joined: Jun 19, 2010
Ok i have had another look at the code, and i actually think that your server is pretty close to the mark. the problem is that you are not actually sending the message the second time. to confirm this.
1. start your server.
2. start your client and send a message.
3. shut down the client.
4. restart your client and send your second message.
The reason your server is not responding is because it is a the ssoc.accept() line is blocking waiting for another connection. I guess the question becomes are you expecting the client to just have one connection to the server or are you expecting it to create a new connection with each new message and then close it down. If its a new connection each time then you will need to modify your client code ( the action associated with the send button) to create the socket and the output stream.
Joined: Dec 19, 2009
Thank you so much Steve, i'm really grateful to you. What you suggested is to create a socket every time send button is clicked, i did that and it worked. Now there is no problem. Thank you so much again.
But i still can't understand what was the mistake. I mean, i'm kind of confused with this whole threading issues. Let me explain my confusion:
Let us analyse the solution "I POSTED EARLIER" step by step from Client point of view:
1)I created a new thread which implements run function. Thus there are two threads: one main and other implementing run. Both get executes time to time depending upon the scheduler.
2)in the run function i created a socket which connects to server at port no 5100:
ss = new Socket(InetAddress.getByName("Invictus-PC"),5100);
3)i fetch the output stream for writing to the socket(i.e. sending data to the server)
output = new ObjectOutputStream(ss.getOutputStream());
4)now i create a server socket at port no 5000:
ssoc = new ServerSocket(5000);
5)now an infinite loop :
in which we wait for request to come:
sen = ssoc.accept();
this thread then hangs until the request comes(or does it mean that the whole program hangs until the request comes? please clarify)
However if the main thread is still working, whenever send button is pressed, the data should be send to the client using the output stream of the socket created to connect to the server in step 1 of run function(that is what was happening,data was being send everytime the send button is pressed,it was happening, that indeed means that main was working and the other thread was at hang and waiting for request to come, now if that is the case why is ssoc.accept() a problem??? and since the data is being sent to the server why is it not accepting and how is server accepting the data(server's working) related to ssoc.accept() blocking the execution)
And one more thing: i fetch the output stream in step 2. This stream is used in the send button code(which is in the main function) I know it is happening but i just want to clarify that can we use an object(initialised in one thread) in another thread?
PS: I tried my level best to explain you the confusion, I'm really messed up.
Joined: Jun 19, 2010
Your implementation seemed torn between establishing a new connection everytime and establishing a connection once an using it to send all of the messages, there also seemmed to be some confusion between the run method and button actions.
The run methods in the client i would only ever expect to recieve incoming messages, ie establish a ServerSocket and enter the loop and waits ( ssoc.accept()) when a connection is established it reads the message, processes it and then goes back to waiting. basically the soul purpose of the run method in your client is to process the incoming messages.
The button press however could have been done in several way's the way it is now is that when the send button is pressed, a new connection ( socket ) is made to the server and the message is sent and then the connection is closed, the otherway todo it would be to establish a socket that you could send multiple messages down, although that would require your server to be smarter, ie be able to handle multiple, connections basically accept connection fork a process to handle the new connection and go back to waiting for another connection, to see what im talking about check out the snippet of code i found at http://oreilly.com/catalog/javanut3/chapter/ch04.html#ch04_11.html ( I used to love this book)
Joined: Dec 19, 2009
Thanks again for the reply.....
Just tell me one thing buddy,
why is this Client Code not giving expected result:
String s = (String) input.readObject();
int i = s.indexOf(",",0);
int j = s.indexOf(",",i+1);
int k = s.indexOf(",",j+1);
String s1 = s.substring(0,i);
String s2 = s.substring(i+1,j);
String s3 = s.substring(j+1);
jTextArea2.append("New Message Recieved and the Details are as under:\n");
jTextArea2.append("Message sent by: "+s1+"\n");
jTextArea2.append("Message subject is: "+s2+"\n");
jTextArea2.append("Actual message is: "+s3+"\n \n \n \n");
while this modification produces exact desirasable results:
when this is being written, a request is send, and we retrieve c in ss.
However when i write on Client:
does that mean ss gets closed? (And vice versa, if i close ss does it mean c gets closed?)
Joined: Jun 19, 2010
Im not exactly sure where you are getting confused, but i can see that you still have the button action overlapping with the run method the run method should not be referencing the output stream, the output stream should only be used by the button action. the run method is only responsible receiving the messages back from the server and does nothing to send the message to the server.
so i will explain the server,
1. you establish the ServerSocket,
2. while true
3. wait for connection (ssoc.accept())
4. process request from socket
5. close connection
6. return to 2.
The button action in the client will have the following function on each press.
7. establish connection.
8. push the message.
9. close the connection.
your server is blocking at 3 and it will keep blocking until a connection is established, notice there is no mention of the run method from the client, this is only used to receive messages from the server, The run method is responsible from receiving the messages from the server and has nothing todo with the sending, you could not invoke the start() method in the client main, and the client would still be able to send.
You dont have to close the socket on both ends but its best practice todo, as you will get errors if you try and read from a closed socket and if you have explicitly closed it. You have a simple contract between your client and server, they both know that after one message they can close the connection.