Witam.
Korzystając z tego tutoriala: http://cs.lmu.edu/~ray/notes/javanetexamples/#chat próbowałem stworzyć aplikację działającą na socketach. Dokładniej czat.
Stworzyłem sobie 5 klas:
ChatClient - odpowiada za gui oraz komunikację z serwerem
CommunicationServer - serwer tworzący ServerSocket i nasłuchujący kolejnych klientów
CommunicationServerConsole - aplikacja okienkowa - konsola serwera (przekierowuje System.out na textArea tego frame'a)
TextAreaPrintStream - klasa, która pozwala mi wypisać w textArea treści, które są wypisywane na konsolę
CommunicationHandler - klasa odpowiadająca za inicjalizację oraz komunikację z klientem
Niestety pojawił się problem: aplikacja zawiesza się na linii, która próbuje wypisać na OutputStream klienta tekst (CommunicationHandler.java:52) nie pokazując żadnego komunikatu, ani Exceptiona. Pozwoliłem sobie usunąć importy oraz gettery i settery w kodach źródłowych oraz nie dołączyłem pliku TextAreaPrintStream, ponieważ nie ma on żadnego znaczenia w moim problemie. Klasą startującą dla serwera jest CommunicationServerConsole, dla klienta - ChatClient.
@SuppressWarnings("serial")
public class CommunicationServerConsole extends JPanel {
private JTextArea textArea = new JTextArea(15, 30);
private TextAreaPrintStream taps = new TextAreaPrintStream(
textArea, "Server");
public CommunicationServerConsole() {
setLayout(new BorderLayout());
add(new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
System.setOut(taps);
textArea.setEnabled(false);
textArea.setFont(new Font("Arial Unicode MS", Font.PLAIN, 12));
textArea.setBackground(Color.BLACK);
}
private static void init() {
JFrame frame = new JFrame("Communication Server Console");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new CommunicationServerConsole());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
init();
CommunicationServer.getInstance();
}
}
final public class CommunicationServer {
private static volatile CommunicationServer instance = null;
private static final int PORT = 9001;
private HashMap<String, PrintWriter> clients = new LinkedHashMap<String, PrintWriter>();
private CommunicationServer() {
try {
System.out.println("Initializing server chat...");
createServer();
} catch (IOException ex) {
Logger.getLogger(CommunicationServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static CommunicationServer getInstance() {
if (instance == null) {
synchronized (CommunicationServer.class) {
if (instance == null) {
instance = new CommunicationServer();
}
}
}
return instance;
}
public void createServer() throws IOException {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Server was created successfully.");
try {
while (true) {
new CommunicationHandler(serverSocket.accept()).start();
}
} finally {
serverSocket.close();
}
}
}
public class CommunicationHandler extends Thread {
private String nick;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public CommunicationHandler(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
createNickname();
listening();
} catch (IOException ex) {
Logger.getLogger(CommunicationHandler.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (nick != null) {
CommunicationServer.getInstance().getClients().remove(nick);
}
try {
socket.close();
} catch (IOException ex) {
Logger.getLogger(CommunicationHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void createNickname() throws IOException {
while (true) {
out.println("$nick");
nick = in.readLine();
if (nick == null || "".equals(nick)) {
return;
}
synchronized (CommunicationServer.getInstance().getClients()) {
if (!CommunicationServer.getInstance().getClients().containsKey(nick)) {
CommunicationServer.getInstance().getClients().put(nick, out);
out.println("$nickaccepted");
break;
} else {
out.println("Nickname is occupied.");
}
}
}
}
private void listening() throws IOException {
while (true) {
String input = in.readLine();
if (input == null || "".equals(input)) {
return;
}
for (PrintWriter writer : CommunicationServer.getInstance().getClients().values()) {
writer.println("MSG " + nick + ": " + input);
}
}
}
}
public class ChatClient {
private Boolean isConnected = false;
private BufferedReader in;
private PrintWriter out;
private JFrame frame = new JFrame("Chat");
private JTextField textField = new JTextField(40);
private JTextArea messageArea = new JTextArea(8, 40);
public ChatClient() {
textField.setEditable(false);
messageArea.setEditable(false);
frame.getContentPane().add(textField, "North");
frame.getContentPane().add(new JScrollPane(messageArea), "Center");
frame.pack();
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(textField.getText());
textField.setText("");
}
});
}
private String getServerAddress() {
return JOptionPane.showInputDialog(
frame,
"Enter IP Address of the Server:",
"Welcome to the chat",
JOptionPane.QUESTION_MESSAGE);
}
private String getName() {
return JOptionPane.showInputDialog(
frame,
"Choose a screen name:",
"Screen name selection",
JOptionPane.PLAIN_MESSAGE);
}
private void connectToServer() throws UnknownHostException, IOException {
String serverAddress = getServerAddress();
Socket socket = new Socket(serverAddress, 9001);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
isConnected = true;
}
private void run() {
do {
try {
connectToServer();
while (true) {
String line = in.readLine();
if (line.startsWith("$nick")) {
out.println(getName());
} else if (line.startsWith("$nickaccepted")) {
textField.setEditable(true);
} else if (line.startsWith("MSG")) {
messageArea.append(line.substring(8) + "\n");
}
}
} catch (ConnectException | UnknownHostException e) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, "Nie odnaleziono hosta.");
} catch (IOException e) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, "Błąd połączenia.");
}
} while (!isConnected);
}
public static void main(String[] args) throws Exception {
ChatClient client = new ChatClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}
Proszę o pomoc.