Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: Java socket
i have wtited a socket server application in java,it works good but after some connecting and disconnecting of client sockets ,the cpu usage of the application goes above the 65%
are there any problem with my code ?
this is my server application :
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
 
public class Server {
 
static final int PORT = 2012;
 

	private static HashSet<DataOutputStream> writers = new HashSet<DataOutputStream>();
 
	public static void main(String[] args) throws Exception {
		System.out.println("The chat server is running.");
		ServerSocket listener = new ServerSocket(PORT);
		try {
			while (true) {
				new Handler(listener.accept()).start();
			}
		} finally {
			listener.close();
		}
	}
 

	private static class Handler extends Thread {
		private Socket socket;
		private DataInputStream in ;
		private DataOutputStream out;
 

		public Handler(Socket socket) {
			this.socket = socket;
		}
 
		public void run() {
			try {
			in = new DataInputStream(socket.getInputStream()) ;
			out =new DataOutputStream(socket.getOutputStream() );
 
				
				writers.add(out);
 
				
				while (true) {
					byte [] input = new byte [1024]; 
					int count = in.read(input);
					if (count > 0) {
						
					for (DataOutputStream writer : writers) {
						
						writer.write(input,0,count);
						
						}
					}
					
					 if ( input.equals("bye.")) {
						break ;
				}
			} // end of while
			} catch (IOException e) {
				System.out.println(e);
			} finally {
 
				
				if (out != null) {
					writers.remove(out);
				}
				try {
					socket.close();
				} catch (IOException e) {
				}
			}
			
	}
	}
}
Posted 8-Jul-13 7:14am
Edited 8-Jul-13 7:32am
v2
Comments
pasztorpisti at 8-Jul-13 13:45pm
   
There is one obvious bug that must be fixed before searching for any other bugs: Since you are accessing your writers map from multiple threads and its not a constant readonly data structure you should protect it with a lock. Before correct multithreading there is no point of searching for other bugs.
http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
 
You can do this for example by using the writers collection only inside synchronized(writers) { (using the writers collection) } blocks.
Reza Oruji at 8-Jul-13 14:08pm
   
thank you.maybe that's the main problem.let me try it
pasztorpisti at 8-Jul-13 15:12pm
   
You are welcome. Next time press the reply button on the comment you are replying to otherwise the other guy doesn't receive notification about your message. Its just blind luck tha I got back here. There is another bug that probably happens rarely especially if you are using your program on a fast local network: When you are reading the socket never assume that you read the data out in the same chunks in which you have written the data to the socket on the other side. If the data is relatively small (less than the MTU of your network) and you are using quite deterministic/reliable/fast network then small writes often arrive in one piece, but always assume that the data you write to the socket has no separators between the writes. Lets say you write "bye." to the socket, in theory it can happen that you can read it out from the socket only with 4 reads and each read reads out only 1 byte. For this reason it can happen that your "bye." message gets splitted into many pieces or you may read it out from the socket with another message that was sent before the "bye.". To send messages you should somehow separate the messages, for example starting every message with an integer that tells you how many bytes follow as the body of this message. Or you could simply use a special character to separate the messages. When you read out data from the socket you should collect the bytes into a buffer. When you receive a few bytes you just append it to the buffer and then you run an algorithm that checks whether you have full arrived messages at the beginning of the buffer closed with a separator byte. If yes, then you send it to other clients and then you remove the message with its closing separator from the buffer. Warning: It can happen that you receive a lot of messages together with several separators in the stream with one read. Another thing you must handle that you may receive the end of a message with a separator and in the same message you may get the first few bytes of the next message as well! When you remove the fully received message you must leave the beginning bytes of the next message in the buffer!
 
If you want a test case in your code for the fragmentation of message receiver part: For the time of testing replace your socket reader code that intentionally reads at most 1 byte from the socket! This way you simulate the worst case when the message is received as fragmented to 1 byte pieces. This way you test most of your code that handles message fragmentation!
Reza Oruji at 8-Jul-13 17:20pm
   
THANK YOU :))
pasztorpisti at 8-Jul-13 17:44pm
   
You are welcome!
Reza Oruji at 10-Jul-13 4:51am
   
hello ,another problem that i have is that after connecting and disconnecting of the client,for second time the client can not connect to server again and i need to close and reopen the server program and then connect from client.can you please help me ?
pasztorpisti at 10-Jul-13 8:31am
   
I would first put in logging to the server. With that you could find out where the server hangs up. A better solution would be running your server in a debugger (for example eclipse or netbeans) and in the debugger you can always pause the server and check out the number of threads and the callstack of each thread.
Reza Oruji at 10-Jul-13 11:55am
   
Good idea.thank you
Amitosh S.M. at 11-Jul-13 1:29am
   
Are you on a poor connection and windows?
Such an issue usually arises if your client is behind a low-latency/poor network with huge packet loss. Or there may be a large number of concurrent connections. Your code has nothing to do with this. If there is a huge packet-loss, large amount of data has to be retransmitted causing high load on the CPU. The underlying tcp stack may have the problem. In windows, I've seen this in any networked app, regardless of the language.
pasztorpisti at 11-Jul-13 4:38am
   
With internet connection and poor routes this can happen (especially with poorly implemented UDP communication) but I guess he is just developing this on his own machine and its TCP. Local loopback connections are handled specially by windows bypassing the network stack (at least partially) so his example should work perfectly on a single machine if its not buggy. I remember that I had to install additional drivers that forced the loopback connections to go through the network stack correctly in order to be able to capture the data flow of my locally tested programs with wireshark.
Amitosh S.M. at 11-Jul-13 7:27am
   
Yeah, that's right.
Reza Oruji at 11-Jul-13 9:08am
   
i installed it on a VPS ruuning windows server and connect to it from my machine.
Amitosh S.M. at 12-Jul-13 2:16am
   
Do you have a very high latency connection (low bandwidth,high ping etc.)
Reza Oruji at 12-Jul-13 5:09am
   
this is the ping result :
Approximate round trip times in milli-seconds:
Minimum = 198ms, Maximum = 210ms, Average = 202ms
Wiimax at 15-Jul-13 3:54am
   
Hi. This ping time seems quite long and could indicate that your connection may be doing a few hops before the packets get to the server. I'd say Amitosh is probably on track with the packet loss. I've seen similar issues with TCP related client/server where optimising the network layer reduced the CPU loading because in the background the stack is just constantly waiting for data and the timeouts are long - the thread just sits waiting. Various workarounds include a separate timer that just drops connections that haven't responded thus reducing the CPU load. Other issue might be the firewall on the server taking a long time to process requests and pass them on. Does it improve if you whitelist your IP for a session? If the ICMP response is a little slow then the actual data I/O may be longer still.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 325
1 DamithSL 265
2 CPallini 235
3 Maciej Los 190
4 Sergey Alexandrovich Kryukov 189
0 OriginalGriff 5,455
1 DamithSL 4,422
2 Maciej Los 3,860
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,010


Advertise | Privacy | Mobile
Web02 | 2.8.141216.1 | Last Updated 8 Jul 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100