套接字阻塞与收到的消息不一致

时间:2018-04-10 17:48:51

标签: java multithreading sockets

我正在为我的聊天客户端系统编写测试,该系统适用于套接字和1个服务器。我创建了3个套接字(每个代表客户端的线程),选择聊天室(“美国房间”),所有发送1条消息,这是我做的 - 启动服务器,等待所有客户进入房间,每个发送消息,然后从每个套接字读取所有消息,关闭服务器,但是在读取某些套接字消息时,测试会冻结。这种冻结是由这一行引起的:String line = reader.readLine();。一些套接字接收到正确数量的消息(即5),其他套接字只是冻结了小于5的消息。我无法理解套接字冻结的原因。

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 ");
    }
}

服务器类:

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!");

    }

}
}

1 个答案:

答案 0 :(得分:0)

PrintWriter stream = new PrintWriter(allsockets.get(i).getOutputStream(), true);
stream.println(linesFromFile.get(i));

不写入此客户端套接字,它会向其连接的服务器发送消息。服务器在哪里写入5行到每个客户端套接字,你在这里阅读:

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);
        // ...

最好是转储所有代码,然后我才能真正提供帮助。事实上,你并没有真正帮助我。