Revision: 14158
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at May 20, 2009 22:25 by mcox05
Initial Code
In a nutshell, I just recently starting attempting to use Sockets and decided I wanted to give a go at a chat program. I have some experience with threads and based on the weird deadlock issues I have come to the conclusion that I must have some non thread-safe calls somewhere. Any help would be appreciated. *Client-Side Files* {code} public class Client extends Thread { private Socket conn; private ObjectOutputStream out; private ObjectInputStream in; public Client() { conn = null; out = null; in = null; } public Client(String ip) { obsList = new ArrayList<IClientObs>(); try { conn = new Socket(ip, 5000); if (conn.isConnected()) { out = new ObjectOutputStream(conn.getOutputStream()); in = new ObjectInputStream(conn.getInputStream()); } notify("Server: Welcome! Connected to '" + conn.getRemoteSocketAddress() + "'.\n"); } catch(IOException e) { notify("Console: Error while attempting to connect to the server.\n"); System.err.println("ConnClient:: ConnClient() -> " + e.getMessage() + "\n"); } } public Client(Socket pConn) { obsList = new ArrayList<IClientObs>(); try { conn = pConn; if (conn.isConnected()) { out = new ObjectOutputStream(conn.getOutputStream()); in = new ObjectInputStream(conn.getInputStream()); } notify("Server: Welcome! Connected to '" + conn.getRemoteSocketAddress() + "'.\n"); } catch(IOException e) { notify("Console: Error while attempting to connect to the server.\n"); System.err.println("ConnClient:: ConnClient() -> " + e.getMessage() + "\n"); } } public void run() { while (conn.isConnected()) { nextMsg(); } } public String nextMsg() { String msg = ""; try { msg = (String)in.readObject(); notify(msg); } catch(IOException e) { System.err.println("ConnClient:: nextMsg() -> " + e.getMessage() + "\n"); } catch(ClassNotFoundException e) { System.err.println("ConnClient:: nextMsg() -> " + e.getMessage() + "\n"); } finally { //notify("Console: Error while attempting to read messages from server.\n"); } return(msg); } public boolean sendMsg(String msg) { boolean sentMsg = false; try { if (out != null) { out.writeObject(msg); out.flush(); sentMsg = true; } } catch(IOException e) { notify("Console: Error while attempting to send message to server.\n"); System.err.println("ConnClient:: sendMsg() -> " + e.getMessage() + "\n"); } return(sentMsg); } public void closeConn() { try { if (conn != null && in != null && out != null) { notify("Server: you have been disconnected from '" + conn.getRemoteSocketAddress() + "'.\n"); sendMsg("~~QUIT~~"); conn.close(); in.close(); out.close(); } } catch(IOException e) { notify("Console: Error while closing connection."); } } public String getIP() { return(conn.getRemoteSocketAddress().toString()); } public boolean isConnected() { return(conn.isConnected()); } private ArrayList<IClientObs> obsList; public void addObserver(IClientObs obs) { if (obs != null) { obsList.add(obs); } } public void delObserver(IClientObs obs) { if (obs != null) { obsList.remove(obs); } } private void notify(String msg) { for(IClientObs obs : obsList) obs.update(msg); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// public interface IClientObs { public void update(String msg); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class ClientGui implements ActionListener, KeyListener, IClientObs { private JLabel statusLbl; private JTextField chatTB, ipTB; private JTextArea txtArea; private JButton submitBtn, connectBtn, disconnBtn; private JList membList; private Container cont; private JFrame frame; private Client client; public ClientGui() { init("Client Chat"); frame.setBounds(100,100,600,500); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } private void init(String title) { frame = new JFrame(title); cont = frame.getContentPane(); submitBtn = new JButton("Send"); connectBtn = new JButton("Connect"); disconnBtn = new JButton("Disconnect"); txtArea = new JTextArea(); chatTB = new JTextField(30); ipTB = new JTextField(16); statusLbl = new JLabel("Status:: Not Connected"); membList = new JList(new String[]{"admin"}); JLabel ipLbl = new JLabel("IP Address:"); JPanel paneE = new JPanel(); txtArea.setEditable(false); paneE.setLayout(new BorderLayout()); Box boxS = new Box(BoxLayout.X_AXIS); boxS.add(chatTB); boxS.add(Box.createHorizontalStrut(2)); boxS.add(submitBtn); Box boxC = new Box(BoxLayout.Y_AXIS); boxC.add(new JScrollPane(txtArea)); boxC.add(Box.createVerticalStrut(5)); Box boxE = new Box(BoxLayout.Y_AXIS); boxE.add(new JLabel("IP Address:")); boxE.add(ipTB); Box boxI = new Box(BoxLayout.X_AXIS); boxI.add(connectBtn); boxI.add(Box.createHorizontalStrut(2)); boxI.add(disconnBtn); boxE.add(boxI); boxE.add(Box.createVerticalStrut(5)); paneE.add(boxE, BorderLayout.NORTH); paneE.add(membList, BorderLayout.CENTER); cont.add(statusLbl, BorderLayout.NORTH); cont.add(boxC, BorderLayout.CENTER); cont.add(boxS, BorderLayout.SOUTH); cont.add(paneE, BorderLayout.EAST); ipLbl.setHorizontalAlignment(SwingConstants.LEFT); boxE.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); statusLbl.setPreferredSize(new Dimension((int)statusLbl.getSize().getWidth(), 30)); membList.setBorder(BorderFactory.createLineBorder(Color.black)); txtArea.setEditable(false); connectBtn.addActionListener(this); disconnBtn.addActionListener(this); submitBtn.addActionListener(this); chatTB.addKeyListener(this); } private void connect() { String ip = ipTB.getText(); client = new Client(ip); client.addObserver(this); client.start(); connectBtn.setEnabled(false); disconnBtn.setEnabled(true); submitBtn.setEnabled(true); } private void disconnect() { client.closeConn(); client = null; connectBtn.setEnabled(true); disconnBtn.setEnabled(false); submitBtn.setEnabled(false); } private void sendData() { if (client != null && client.isConnected()) { String msg = chatTB.getText(); client.sendMsg(msg); } } public void actionPerformed(ActionEvent e) { Object src = e.getSource(); if (src == submitBtn) { sendData(); } else if (src == connectBtn) { connect(); } else if (src == disconnBtn) { disconnect(); } } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { int key = e.getKeyChar(); if (key == KeyEvent.VK_ENTER) sendData(); } public void update(String msg) { txtArea.append(msg); } } {code} *Server-Side Files* {code} public class ConnClient extends Thread { private Socket conn; private ObjectOutputStream out; private ObjectInputStream in; public ConnClient() { conn = null; out = null; in = null; } public ConnClient(Socket pConn) { try { conn = pConn; if (conn.isConnected()) { out = new ObjectOutputStream(conn.getOutputStream()); in = new ObjectInputStream(conn.getInputStream()); } } catch(IOException e) { System.err.println("ConnClient:: ConnClient() -> " + e.getMessage() + "\n"); } } public String nextMsg() { String msg = ""; try { msg = (String)in.readObject(); } catch(IOException e) { System.err.println("ConnClient:: nextMsg() -> " + e.getMessage() + "\n"); } catch(ClassNotFoundException e) { System.err.println("ConnClient:: nextMsg() -> " + e.getMessage() + "\n"); } catch(NullPointerException e) { System.err.println("ConnClient:: nextMsg() -> " + e.getMessage() + "\n"); } return(msg); } public boolean sendMsg(String msg) { boolean sentMsg = false; try { if (out != null) { out.writeObject(msg); out.flush(); sentMsg = true; } } catch(IOException e) { System.err.println("ConnClient:: sendMsg() -> " + e.getMessage() + "\n"); } return(sentMsg); } public void closeConn() throws IOException { if (conn != null && in != null && out != null) { conn.close(); in.close(); out.close(); } } public String getIP() { return(conn.getRemoteSocketAddress().toString()); } public boolean isConnected() { return(conn.isConnected()); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// public interface IServerObs { public void update(String msg); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class ServerGui implements ActionListener, IServerObs { private JFrame frame; private Container cont; private JButton strBtn, stpBtn; private JTextArea console; private Server server; public ServerGui() { frame = new JFrame("Chat Server"); cont = frame.getContentPane(); strBtn = new JButton("Start Server"); stpBtn = new JButton("Stop Server"); console = new JTextArea(); strBtn.addActionListener(this); stpBtn.addActionListener(this); Box b = Box.createHorizontalBox(); b.add(strBtn); b.add(Box.createHorizontalStrut(3)); b.add(stpBtn); cont.add(new JScrollPane(console), BorderLayout.CENTER); cont.add(b, BorderLayout.SOUTH); Toolkit kit = frame.getToolkit(); Dimension d = kit.getScreenSize(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(d.width/4, d.height/4, ((int)(d.width/1.75)), ((int)(d.height/1.75))); frame.setVisible(true); } public void actionPerformed(ActionEvent e) { Object src = e.getSource(); if (src == strBtn) { if (server == null) { strBtn.setEnabled(false); stpBtn.setEnabled(true); server = new Server(); server.addObserver(this); server.start(); } else { console.append("Console: Server is alread initiated.\n"); } } else if (src == stpBtn) { strBtn.setEnabled(true); stpBtn.setEnabled(false); server.shutdown(); server = null; console.append("Console: Server has been stopped.\n"); } } public void update(String msg) { console.append("Console: " + msg + "\n"); } } {code} lol, sorry for so much code but I figured it would be necessary for context and figuring out where the problem is.
Initial URL
Initial Description
Initial Title
Client/Server Chat Program
Initial Tags
Initial Language
Java