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