Reputation: 11
I'm writing test for my chat-client system which works with sockets and 1 server. I have created 3 sockets(each one in thread representing client) which choose chat-room( "USA room") and all send 1 message, here is what I do-start the server, wait all clients to come in the room, each send a message, then read all messages from each socket,shutdown server, however while reading some socket's messages the test freezes. This freezing is caused by this line: String line = reader.readLine();
. Some sockets receive the right amount of messages (which is 5), others just freeze with messages less than 5. I can't figure why the socket freeze.
public class ChatTest {
final int NUMBER_OF_SOCKETS = 3;
Server server = new Server();
Map<String, Socket> mapSockets = new ConcurrentSkipListMap<>();
List<String> socketMessages = new CopyOnWriteArrayList<>();
List<Thread> allThreads = new CopyOnWriteArrayList<>();
List<Socket> allsockets = new CopyOnWriteArrayList<>();
Set<Set<String>> allSets = new HashSet<>();
Map<Thread, Socket> mapThreadSocket = new ConcurrentHashMap<>();
private final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_SOCKETS);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
server.start();
}
});
@BeforeSuite(alwaysRun = true)
public void startServer() {
t.start();
}
@AfterSuite(alwaysRun = true)
public void stopServer() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
server.stop();
}
Thread t2 = new Thread() {
@Override
public void run() {
try {
final List<String> linesFromFile = ChatSystemUtils.readFromFile(ClientTestDataConstants.TestDataFile.toString(), 50);
System.out.println("all client threads have entered room called USA room ");
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
final PrintWriter stream = new PrintWriter(allsockets.get(i).getOutputStream(), true);
mapSockets.put(linesFromFile.get(i), allsockets.get(i));
stream.println(linesFromFile.get(i));
socketMessages.add(i, linesFromFile.get(i));
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(allsockets.get(i).getInputStream()));
System.out.println("AT NEW USER");
Set<String> userMessages = new HashSet<>();
for (int j = 0; j < 5; j++) {
String line = reader.readLine();
System.out.println(line);
if (j > NUMBER_OF_SOCKETS) {
String msg = line.substring(9, line.length());
userMessages.add(msg);
}
}
userMessages.add(socketMessages.get(i));
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
@Test
public void testMessagesReceived() throws IOException {
List<Thread> threadList = new LinkedList<>();
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e1) {
e1.printStackTrace();
}
try {
Socket socket = new Socket("127.0.0.1", 3000);
allsockets.add(socket);
final PrintWriter stream = new PrintWriter(socket.getOutputStream(), true);
stream.println("USA room");
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(r);
threadList.add(t);
}
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).start();
}
for (int i = 0; i < threadList.size(); i++) {
try {
threadList.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("most of the times we don't get here ");
}
}
Server class :
public final class Server {
public static boolean stopServerCalled;
private final int port;
private final String host;
private final Map<String, ChatRoom> mapRooms = ChatServerUtils.getChatRooms();
private final AtomicInteger clientID = new AtomicInteger(1);
private ServerSocket serverSocket;
private List<IClient> clientsPickingRoom;
private final ExecutorService executorService = Executors.newCachedThreadPool();
public Server() {
final Properties prop = new Properties();
try (final InputStream inputStream = getClass()
.getResourceAsStream("/com/egt/chat/server/ChatServerConfig.properties")) {// read from a file of
// properties
prop.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
this.port = Integer.parseInt(prop.getProperty("port"));
this.host = prop.getProperty("host");
this.clientsPickingRoom = new CopyOnWriteArrayList<>();
}
public void start() {
try {
final InetAddress address = InetAddress.getByName(host);
serverSocket = new ServerSocket(port, 50, address);
System.out.println("Listening on socket : " + serverSocket);
while (!Thread.currentThread().isInterrupted()) {
final Socket newSocket = serverSocket.accept();
System.out.println("Connection established with: " + newSocket);
final ClientContainer newClient = new ClientContainer(clientID.get(), newSocket);
executorService.execute(new ClientContainerRunnable(newClient, this));
clientID.incrementAndGet();
clientsPickingRoom.add(newClient);
}
} catch (IOException e) {
System.out.println("Server stopped!");
}
}
}
Upvotes: 0
Views: 48
Reputation: 4699
PrintWriter stream = new PrintWriter(allsockets.get(i).getOutputStream(), true);
stream.println(linesFromFile.get(i));
Isn't writing to this client socket, it's sending a message out to the server it's connected to. Where is the server writing the 5 lines to each client socket, which you read here:
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(allsockets.get(i).getInputStream()));
for (int j = 0; j < 5; j++) {
String line = reader.readLine();
System.out.println(line);
// ...
It may be best if you dump all your code, then I could actually help. As it is, you aren't really helping me help you.
Upvotes: 0