Click here to Skip to main content
15,507,388 members
Please Sign up or sign in to vote.
5.00/5 (3 votes)
See more:
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 :
Java
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
Updated 8-Jul-13 7:32am
v2
Comments
pasztorpisti 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 8-Jul-13 14:08pm    
thank you.maybe that's the main problem.let me try it
pasztorpisti 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 8-Jul-13 17:20pm    
THANK YOU :))
pasztorpisti 8-Jul-13 17:44pm    
You are welcome!

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900