/* CSC 175 Programming Assignment : Multi-Client Chat Program For this extra assignment you are to write a chat program that has the functionality of the program I demonstrated in class. This program will need to include the OVOAP authentication protocol implementation of the previous assignment, so you won't be chatting with any impostors. Your program must be capable of being either client or server. This can be done by first trying to be client, and if no connection can be made (exception will be thrown) then become a server. The server port should be 33333. The server should create a new window (echat object - see below) for each client, and should be capable of accepting connections from multiple clients, so you can talk to multiple people at the same time. After connection has been established, the client and server will then execute the OVOAP protocol using the authentication server on deepdish, 10.1.0.98:21004, just as before. If authentication is successful, the chating can commence. However, all data exchanged should be in binary form, in chunks of 512 bytes. ****** USE THE SESSION KEY (keys) provided by the authentication server to XOR the data before transmitting, so your nasty neighbors can't read your gossip using wireshark. Obviously, at the receiving end, the data needs to be XOR'ed with the session key again before displaying. If authentication is not successful, use your imagination. See the WWW Proxy program as an example. However, you should only need to create one thread in addition to the main thread of your program. I'm also giving you a gui skeleton. If you write this program in some language other than java you will have to use another gui API, which I do not recommend. Inside the echat class, you need to understand the following: There are four GUI elements: inputfield: this is where text should be entered outputarea and inputarea : windows where text can be displayed clearbutton: a button that should clear all text from GUI inputfield.getText() returns a String representing the text found in the inputfield. inputarea.setText("..") or inputarea.append(".."); sets or adds new text to the windows. Thus *.setText(""); will clear current contents. The method ActionPerformed in the echat class is called whenever you hit return after typing a message, or when you click on the clear button. This is where you must add code to send the appropriate string through a socket. When a connection is first established, you should display a message in one of the windows to indicate the ip address of the connected peer. (cfd.getInetAddress()). The echat window should have code (I suggest you put it in init()) that creates a new thread when opened, because information can travel in either direction at any time. FINALLY, for protection from SYN-flood DOS attacks, your program should limit the number of simultaneous windows that are open. Your program needs to be compatible with everyone else's program. EXTRA CREDIT: Give this program the option of using UDP instead of TCP, since the packets communicated are not large. You program should first try to establish/wait for a UDP connection before trying TCP. The port numbers should be the same. Note that the OVAP authenication part of your program should still use TCP, because that's what the server understands. */ /* Chat program GUI Skeleton */ import javax.swing.*; import java.awt.*; import java.awt.Graphics; import java.awt.event.*; import java.io.*; import java.net.*; public class chatgui { public static int SERVERPORT = 33333; // official protocol port public static void main(String[] args) throws Exception { Socket cfd = null; ServerSocket sfd = null; /* The main procedure should either connect to servers specified in args[0]. If no args specified, or if connection fails, it should enter into a server loop and wait for connections. something like the following should work: boolean beclient = false; try { cfd = new Socket(serverip, SERVERPORT); beclient = true; } catch (SocketException ee) {} // thrown if server not up if (!beclient) // be server instead { sfd = new ServerSocket(SERVERPORT); cfd = sfd.accept(); // wait for client connection } Whenever a connection is established, either as client or from sfd.accept(), you should create a new instance of the echat window, passing to the constructor the socket (cfd) that was just created. Your server loop should continue to execute so you can have multiple windows open to multiple clients. HOWEVER, YOU MAY WISH TO MAKE IT WORK FOR JUST TWO PEERS FIRST. */ // Sample code to produce a window (delete this in your program) echat chatwindow = new echat(cfd); chatwindow.init(); // should you choose to write a init proc. } //main } // chatgui class class echat extends JFrame implements ActionListener { public static int SERVERPORT = 33333; public JTextArea outputarea; // multi-line editible areas public JTextArea inputarea; public JTextField inputfield; // single line editible area public JScrollPane scroller; // to make an element scrollable public JScrollPane scroller2; // to make an element scrollable public JButton clearbutton; // clears fields // socket object and associated communicators public Socket cfd; public DataInputStream din; public DataOutputStream dout; // use myutils.bufToString/stringToBuf to embed/extract strings from byte[] public echat(Socket s0) throws Exception { cfd = s0; outputarea = new JTextArea("Incomming messages:\n"); inputarea = new JTextArea("Outgoing messages:\n"); inputfield = new JTextField(80); scroller = new JScrollPane(outputarea); scroller2 = new JScrollPane(inputarea); clearbutton = new JButton("Clear"); scroller2.setBounds(10,10,400,200); scroller.setBounds(10,240,400,200); inputfield.setBounds(10,450,400,30); clearbutton.setBounds(150,500,100,30); Container pane = this.getContentPane(); pane.setLayout(null); pane.add(scroller2); pane.add(scroller); pane.add(inputfield); pane.add(clearbutton); inputfield.addActionListener(this); clearbutton.addActionListener(this); this.setBounds(10,10,450,640); outputarea.setEditable(false); inputarea.setEditable(false); this.setVisible(true); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { try { dout.close(); cfd.close(); dispose(); } catch (Exception ee) {} } }); inputfield.requestFocus(); // this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } // constructor // this function is called when you hit return after typing a message // or when you hit the clear button. public void actionPerformed(ActionEvent e) { String S; try { if (e.getSource() == clearbutton) { inputfield.setText(""); outputarea.setText(""); inputarea.setText(""); } else // assume e.getSource() is inputfield { // code to be executed after typing new message S = inputfield.getText(); S = S.replaceAll("damn","darn"); S = S.replaceAll("hell ","heck "); S = S.replaceAll("Liang is evil","Liang is good"); S = S.replaceAll("I hate networking","I love networking"); inputarea.append(S+"\n"); // display text locally inputfield.setText(""); // clear input field // you need to send S through socket ... } } catch (Exception ee) {} } // actionPerformed. // args[0] is the remote hostname, public void init() throws Exception // called after constructor { // put in code that creates new thread (you'll need a separate // thread class.) } // init } // echat