2012-06-20 5 views
1

안녕하세요 여러분은 클라이언트 서버 채팅을하고 그것에 부하 테스트를 작성하려고합니다. XMPP처럼 보이는 프로토콜을 사용합니다. 나는 XML을 보내고 파싱한다. 서버를 시작하면 일부 사용자의 경우 제대로 작동합니다. 하지만로드 테스트 중이며 많은 사용자를 시작하고 각 사용자로부터 메시지를 보내고 있습니다. 테스트에서는 새 클라이언트를 만들지 않습니다. 출력 스트림이있는 출력 스레드 만 인스턴스화하고이를 사용하여 메시지를 보냅니다. 서버는 수신 한 메시지를 모든 사용자에게 전송하므로 다른 사용자의 말을 경청하는 사용자를 만듭니다. 그리고 가끔 예외를받을 : 소프트웨어 때문에 연결이 중단되었습니다 : 이것은 내있는 ServerThread가소켓에서 멀티 스레드 클라이언트 서버 채팅. 부하 테스트. recv failed

06:55:49 Guest 9 (online) says : Hello Server. Message number^4 
06:55:49 Guest 9 (online) says : Hello Server. Message number^5 
06:55:49 Guest 11 (online) says : Hello Server. Message number^0 
06:55:49 Guest 4 (online) says : Hello Server. Message number^6 
ERROR ServerThread - Error in reading from stream: java.net.SocketException: Software caused connection abort: recv failed 
ERROR ServerThread - Error in reading from stream: java.net.SocketException: Software caused connection abort: recv failed 
06:55:49 Guest 9 (online) says : Hello Server. Message number^6 

입니다 : RECV이 내 콘솔입니다에 실패했습니다. 사용자를 기다리는 부분은 건너 뜁니다.

public class ServerThread implements Runnable { 
    private static final Logger LOG = Logger.getLogger(ServerThread.class); 
    private XMLProtocol protocol; 
    private Socket socket; 
    private BufferedReader input; 
    private PrintWriter out; 
    private static Date date; 
    private String username; 
    private String status = "online"; 
    private SimpleDateFormat dateFormat; 
    private String buffer = ""; 
    private JAXBContext jaxbContext; 
    private Unmarshaller jaxbUnmarshaller; 

    public ServerThread(Socket s) throws SAXException, IOException, JAXBException { 
     input = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     jaxbContext = JAXBContext.newInstance(XMLProtocol.class); 
     out = new PrintWriter(s.getOutputStream()); 
     username = "Guest " + Server.getUserCounter(); 
     dateFormat = new SimpleDateFormat("hh:mm:ss"); 
     Server.addUser(username, out); 
     date = new Date(); 
     socket = s; 
     new Thread(this); 
    } 

    public void run() { 

     try { 
      while (true) { 
       if (input.ready()) { 
        if (buffer.length() <= 256) { 
         if ((buffer = input.readLine()).toString().endsWith("</XMLProtocol>")) { 

          protocol = new XMLProtocol(); 
          jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
          protocol = (XMLProtocol) jaxbUnmarshaller.unmarshal(new StreamSource(new StringReader(buffer))); 

          switch (ChatCommands.valueOf(protocol.getStatus())) { 
          case LOGIN: { 
           Server.sendToAll(Server.buildResponce("User: " + this.username + " Has been changed nickname on " 
             + protocol.getContent())); 
           this.username = protocol.getContent(); 
           break; 
          } 
          case STATUS: { 
           Server.sendToAll(Server.buildResponce("The user: " + this.username + " Is now:" + protocol.getContent())); 
           this.status = protocol.getContent(); 
           break; 
          } 
          case LOGOUT: { 
           Server.sendResponce(Server.buildResponce(ResponseCommands.DISCONNECT), out); 
           quit(); 
           break; 
          } 
          default: { 
           LOG.trace("Getting message from user: " + username + " recived message: " + protocol.getContent()); 
           date = Calendar.getInstance().getTime(); 
           Server.sendToAll(Server.buildResponce(dateFormat.format(date.getTime()) + " " + username + " (" 
             + this.status + ") " + " says : " + protocol.getContent())); 
           break; 
          } 
          } 
         } 
        } else { 
         Server.sendResponce(Server.buildResponce(ResponseCommands.SENDING_FAILED), out); 
        } 
       } 
      } 

     } catch (IOException e) { 
      LOG.error("Error in reading from stream: " + e); 
     } catch (JAXBException e) { 
      LOG.error("Error in Marshalling: " + e); 
     } finally { 
      try { 
       Server.sendResponce(Server.buildResponce(ResponseCommands.UNEXPECTED), out); 
       quit(); 
       LOG.trace("Socket closed"); 
      } catch (IOException | JAXBException e) { 
       LOG.error("Socket no closed" + e); 
      } 
     } 
    } 

    public void quit() throws IOException, JAXBException { 
     Server.sendToAll(Server.buildResponce("User: " + this.username + " quited")); 
     Server.removeUser(out); 
     socket.shutdownInput(); 
     socket.shutdownOutput(); 
     socket.close(); 
    } 
} 

는 그리고 이것은 내 테스트

public class ServerLoadTest { 

    private static ExecutorService exec = Executors.newFixedThreadPool(1000); 
    private static Socket s[] = new Socket[50];// = new Socket(); 

    public static void main(String[] args) throws JAXBException, UnknownHostException, IOException, InterruptedException, 
      XMLStreamException, ParserConfigurationException, SAXException { 
     exec.execute(new TestServerThread()); // start Server thread 
     Thread.sleep(500); // wait till Server starts. 

     s[0] = new Socket("localhost", 4444); 

     exec.execute(new InputThread(s[0], new BufferedReader(new InputStreamReader(s[0].getInputStream())))); // Start 
                               // one 
     for (int i = 0; i < 20; i++) { 
      exec.execute(new TestClientThread());   
     } 
    } 

} 

class TestClientThread implements Runnable { 
    private static final Logger LOG = Logger.getLogger(TestClientThread.class); 
    private XMLProtocol protocol; 
    private JAXBContext jaxbContext; 
    private Marshaller jaxbMarshaller; 
    private Socket socket; 
    private OutputStream outputStream; 

    public TestClientThread() throws JAXBException, UnknownHostException, IOException, InterruptedException, XMLStreamException, 
      ParserConfigurationException, SAXException { 
     jaxbContext = JAXBContext.newInstance(XMLProtocol.class); 
     jaxbMarshaller = jaxbContext.createMarshaller(); 
     socket = new Socket("localhost", 4444); 
     protocol = new XMLProtocol(); 
     outputStream = socket.getOutputStream(); 

     new Thread(this); 

    } 

    @Override 
    public void run() { 
     try { 

      for (int i = 0; i < 10; i++) { 
       protocol.setContent("Hello Server. Message number^" + i); 
       protocol.setStatus(ChatCommands.MSG.getCommandCode()); 
       jaxbMarshaller.marshal(protocol, outputStream); 
      } 
      protocol.setContent("Hello Server. Message number^"); 
      protocol.setStatus(ChatCommands.LOGOUT.getCommandCode()); 
      jaxbMarshaller.marshal(protocol, outputStream); 


/*   socket.shutdownInput(); 
      socket.shutdownOutput(); 
      socket.close(); 
      Thread.currentThread().interrupt();*/ 

     } catch (JAXBException e) { 
      LOG.trace("Error in marshaling "); 

     } 
    } 
} 

class TestServerThread implements Runnable { 
    private Server server; 

    public TestServerThread() { 
     new Thread(this); 
    } 

    @SuppressWarnings("static-access") 
    @Override 
    public void run() { 
     try { 
      server.main(null); 
     } catch (IOException | JAXBException | ParserConfigurationException | SAXException e) { 
      Assert.assertFalse(false); 
     } 
    } 
} 

답변

0

나도 과거에 이러한 오류를 가지고 있습니다. 이 오류는 동기화되지 않은 리소스로 인해 발생했다고 생각합니다. 하지만 javadoc에서 실수로 나를 가리키는 것을 찾을 수 없었습니다. 사람이 어떻게 우리를 말할 수 있다면, 내가 감사 것 MultiClient/Server. Handle communications

을하지만 :

그래서 나는 데이터가 당신이에서 interessted하는 경우가 내 댓글을 읽는 등 인코딩, 연결 처리를 위해 저지/회색을 사용하기로 결정 무거운 동시 환경에서 일반 오래된 소켓을 사용합니다.

+1

올해 당신은 완전히 옳았습니다.지도에 대한 액세스를 동기화하는 데 문제가있었습니다. 그래서 나는 synchro 문제에 대한 코드를 검토하고 ... 지금은 완벽하게 작동합니다. –

관련 문제