/** * Simple example of Internet server/client pair * * * * Server after accepting a connection * - sends the "Hello! Inversion server ready" message; * - in the infinite loop, reads a line and writes back an inverted line. * * Client establishes a connection with a server, then * sends a lines entered by user to a server and receives any data * from server. Receiving is implemented in a separate thread. * * Both server and client are joined in a single program. * * Written by vvb@mech.math.msu.su */ import java.awt.*; import java.awt.event.*; import java.applet.*; import java.net.*; import java.io.*; public class Invert extends Applet { // Layout constants static final int MARGIN = 10; static final int BUTTON_HEIGHT = 30; static final int VSKIP = 10; static final int HSKIP = 10; static final int BUTTON_WIDTH = 100; static final int LABEL_WIDTH = 150; static final int TEXT_WIDTH = 400; static final int PORT_WIDTH = 80; static final String SERVER_HELLO_MESSAGE = "Hello! \"Inversion\" server ready.\r\n"; // Buttons Button connectButton; Button disconnectClientButton; Button disconnectServerButton; Button listenButton; Button cancelListenButton; Button sendButton; TextField remoteIP; TextField remotePort; TextField serverPort; TextField serverMessage; TextField clientMessage; TextField clientSendData; TextArea clientReceiveData; TextArea serverReceiveData; // Sockets Socket clientSocket = null; ServerSocket listenSocket = null; Socket serverIOSocket = null; // Streams DataOutputStream clientOutput; BufferedReader clientInput; DataOutputStream serverOutput; BufferedReader serverInput; Thread clientThread = null; Thread listenThread = null; Thread serverIOThread = null; public void init() { setLayout(null); setBackground(Color.lightGray); int x = MARGIN; int y = MARGIN; //-------------- Client parameters ----------- Label l = new Label("Remote server IP:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; remoteIP = new TextField(); add(remoteIP); remoteIP.setBounds(x, y, TEXT_WIDTH, BUTTON_HEIGHT); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; l = new Label("Remote server port:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; remotePort = new TextField(); add(remotePort); remotePort.setBounds(x, y, PORT_WIDTH, BUTTON_HEIGHT); x += PORT_WIDTH + HSKIP; connectButton = new Button("Connect to remote server"); add(connectButton); connectButton.setBounds( x, y, TEXT_WIDTH - (PORT_WIDTH + HSKIP), BUTTON_HEIGHT ); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; l = new Label("Client status:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; clientMessage = new TextField(); clientMessage.setForeground(Color.blue); add(clientMessage); clientMessage.setBounds( x, y, TEXT_WIDTH - (HSKIP + BUTTON_WIDTH), BUTTON_HEIGHT ); x += TEXT_WIDTH - BUTTON_WIDTH; clientMessage.setEditable(false); disconnectClientButton = new Button("Disconnect"); add(disconnectClientButton); disconnectClientButton.setBounds(x, y, BUTTON_WIDTH, BUTTON_HEIGHT); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; l = new Label("Data to send:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; clientSendData = new TextField(); add(clientSendData); clientSendData.setBounds( x, y, TEXT_WIDTH - (HSKIP + BUTTON_WIDTH), BUTTON_HEIGHT ); x += TEXT_WIDTH - BUTTON_WIDTH; sendButton = new Button("Send"); add(sendButton); sendButton.setBounds(x, y, BUTTON_WIDTH,BUTTON_HEIGHT); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; l = new Label("Received from server:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; clientReceiveData = new TextArea(); clientReceiveData.setEditable(false); add(clientReceiveData); clientReceiveData.setBounds( x, y, TEXT_WIDTH, 3*BUTTON_HEIGHT + 2*VSKIP ); y += 3*(BUTTON_HEIGHT + VSKIP); x = MARGIN; l = new Label("___________________"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; //-------------- Server parameters ----------- l = new Label("Server port to listen:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; serverPort = new TextField(); add(serverPort); serverPort.setBounds(x, y, PORT_WIDTH, BUTTON_HEIGHT); x += PORT_WIDTH + HSKIP; listenButton = new Button("Listen"); add(listenButton); listenButton.setBounds(x, y, BUTTON_WIDTH, BUTTON_HEIGHT); x += BUTTON_WIDTH + HSKIP; cancelListenButton = new Button("Cancel Listening"); add(cancelListenButton); cancelListenButton.setBounds( x, y, TEXT_WIDTH - (PORT_WIDTH + BUTTON_WIDTH + 2*HSKIP), BUTTON_HEIGHT ); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; l = new Label("Server status:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; serverMessage = new TextField(); serverMessage.setForeground(Color.blue); add(serverMessage); serverMessage.setBounds( x, y, TEXT_WIDTH - (HSKIP + BUTTON_WIDTH), BUTTON_HEIGHT ); serverMessage.setEditable(false); x += TEXT_WIDTH - BUTTON_WIDTH; disconnectServerButton = new Button("Disconnect"); add(disconnectServerButton); disconnectServerButton.setBounds(x, y, BUTTON_WIDTH, BUTTON_HEIGHT); y += BUTTON_HEIGHT + VSKIP; x = MARGIN; l = new Label("Received from client:"); add(l); l.setBounds(x, y, LABEL_WIDTH, BUTTON_HEIGHT); x += LABEL_WIDTH + HSKIP; serverReceiveData = new TextArea(); serverReceiveData.setEditable(false); add(serverReceiveData); serverReceiveData.setBounds( x, y, TEXT_WIDTH, 3*BUTTON_HEIGHT + 2*VSKIP ); y += 3*(BUTTON_HEIGHT + VSKIP); x = MARGIN; ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == connectButton) { onConnect(); } else if (source == disconnectClientButton) { onDisconnectClient(); } else if (source == sendButton || source == clientSendData) { onSend(); } else if (source == listenButton) { onListen(); } else if (source == cancelListenButton) { onCancelListen(); } else if (source == disconnectServerButton) { onDisconnectServer(); } } }; connectButton.addActionListener(al); disconnectClientButton.addActionListener(al); sendButton.addActionListener(al); clientSendData.addActionListener(al); listenButton.addActionListener(al); cancelListenButton.addActionListener(al); disconnectServerButton.addActionListener(al); remoteIP.requestFocus(); } public static void main(String[] args) { Frame f = new Frame("Example of Interner Client-Server Pair"); WindowAdapter wa = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; f.addWindowListener(wa); f.setFont(new Font("Helvetica", Font.PLAIN, 14)); // Add menu bar final MenuBar mb = new MenuBar(); f.setMenuBar(mb); final Menu fileMenu = new Menu("File"); final MenuItem quitItem = new MenuItem("Quit"); fileMenu.add(quitItem); mb.add(fileMenu); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { // System.out.println("Action " + e); if (e.getActionCommand().equals("Quit")) { System.exit(0); } } }; fileMenu.addActionListener(al); Invert inv = new Invert(); f.add("Center", inv); // f.pack(); f.setSize( 2*MARGIN + LABEL_WIDTH + HSKIP + TEXT_WIDTH + HSKIP, 2*MARGIN + 13*(BUTTON_HEIGHT + VSKIP) + 60 // For menu bar ); f.setVisible(true); inv.init(); inv.start(); } void onConnect() { if (clientSocket != null) { // Already connected return; } String ip = remoteIP.getText(); String port = remotePort.getText(); if (ip.equals("") || port.equals("")) { clientMessage.setText( "You must set IP and Port of remote server." ); return; } int p; try { p = new Integer(port).intValue(); } catch (NumberFormatException e) { clientMessage.setText( "Port number is illegal." ); return; } try { clientMessage.setText("Connecting..."); clientSocket = new Socket(ip, p); clientSocket.setSoTimeout(0); // Infinite timeout clientOutput = new DataOutputStream( clientSocket.getOutputStream() ); clientInput = new BufferedReader( new InputStreamReader( clientSocket.getInputStream() ) ); } catch (UnknownHostException e) { clientMessage.setText(ip + ": Unknown host."); return; } catch (IOException e) { clientMessage.setText( "Could not connect: " + e.toString() ); if (clientSocket != null) { try { clientSocket.close(); } catch (IOException ex) {} } clientSocket = null; return; } catch (SecurityException e) { clientMessage.setText( "Could not connect: Security exception" ); if (clientSocket != null) { try { clientSocket.close(); } catch (IOException ex) {} } clientSocket = null; return; } clientMessage.setText("Connected to server."); startClientThread(); } void startClientThread() { Runnable r = new Runnable() { public void run() { clientReceiveData.setText(""); while (clientThread != null) { String s = null; try { s = clientInput.readLine(); if (s == null) { // Probably, disconnected clientMessage.setText( "Disconnected." ); onDisconnectClient(); break; } else { clientReceiveData.append(s + "\r\n"); } } catch (IOException e) { clientMessage.setText( "Disconnected." ); onDisconnectClient(); break; } } } }; clientThread = new Thread(r, "clientThread"); clientThread.start(); } void onDisconnectClient() { clientThread = null; if (clientSocket != null) { try { clientOutput.close(); clientInput.close(); clientSocket.close(); } catch (IOException ex) {} } clientMessage.setText("Disconnected."); clientSocket = null; clientOutput = null; clientInput = null; } void onSend() { String s = clientSendData.getText() + "\r\n"; if (clientOutput != null) { try { clientOutput.writeBytes(s); clientSendData.setText(""); } catch (IOException e) { clientMessage.setText( "Could not send a line: " + e ); } } } void onListen() { if (listenSocket != null) return; // Already listening String port = serverPort.getText(); if (port.equals("")) { serverMessage.setText( "You must set the port of local server." ); return; } int p; try { p = new Integer(port).intValue(); } catch (NumberFormatException e) { clientMessage.setText( "Port number is incorrect." ); return; } try { listenSocket = new ServerSocket(p); listenSocket.setSoTimeout(0); // Infinite tumeout } catch (IOException e) { serverMessage.setText( "Could not listen on port " + port + ": " + e ); return; } catch (SecurityException e) { serverMessage.setText( "Could not listen: Security exception" ); return; } startListenThread(); } void startListenThread() { Runnable r = new Runnable() { public void run() { while (listenThread != null) { if (serverIOSocket != null) { try { listenThread.sleep(10); } catch (InterruptedException e) {} continue; } serverMessage.setText("Listening..."); try { serverIOSocket = listenSocket.accept(); } catch (IOException e) { onCancelListen(); break; } catch (SecurityException e) { serverMessage.setText( "Cannot accept connection: Security exception" ); continue; } startServerIOThread(); } listenThread = null; } }; listenThread = new Thread(r, "listenThread"); listenThread.start(); } void startServerIOThread() { if (serverIOSocket == null) { return; } Runnable r = new Runnable() { public void run() { serverReceiveData.setText(""); try { serverOutput = new DataOutputStream( serverIOSocket.getOutputStream() ); serverInput = new BufferedReader( new InputStreamReader( serverIOSocket.getInputStream() ) ); serverMessage.setText("Connected with client."); serverOutput.writeBytes(SERVER_HELLO_MESSAGE); while (serverIOThread != null) { String s = null; s = serverInput.readLine(); if (s == null) { // Probably, disconnected onDisconnectServer(); break; } else { serverReceiveData.append(s + "\r\n"); serverOutput.writeBytes( invertLine(s) + "\r\n" ); } } } catch (IOException e) { onDisconnectServer(); } serverIOThread = null; } }; serverIOThread = new Thread(r, "serverIOThread"); serverIOThread.start(); } void onCancelListen() { if (listenSocket == null) return; listenThread = null; try { listenSocket.close(); } catch (IOException e) { } serverMessage.setText("Listen is cancelled."); listenSocket = null; } void onDisconnectServer() { serverIOThread = null; if (serverIOSocket == null) return; try { serverOutput.close(); serverInput.close(); serverIOSocket.close(); serverMessage.setText("Disconnected."); } catch (IOException e) { } serverOutput = null; serverInput = null; serverIOSocket = null; } String invertLine(String s) { int l = s.length(); StringBuffer t = new StringBuffer(l); for (int i = l - 1; i >= 0; i--) t.append(s.charAt(i)); return t.toString(); } }