When the java online chat project solves the problem that the client can send messages to the server only once, OutputStreamWriter DataOutputStream socket. getOutputStream (),
Client code before the problem is solved:
Package com. swift; import java. awt. borderLayout; import java. awt. color; import java. awt. event. actionEvent; import java. awt. event. actionListener; import java. awt. event. windowAdapter; import java. awt. event. using wevent; import java. io. bufferedWriter; import java. io. dataOutputStream; import java. io. IOException; import java. io. outputStreamWriter; import java.net. socket; import java.net. unknownHostException; import j Avax. swing. JButton; import javax. swing. JFrame; import javax. swing. JLabel; import javax. swing. JPanel; import javax. swing. JScrollPane; import javax. swing. JTextArea; import javax. swing. JTextField; public class ChatClientFrame2 extends JFrame {private static final long serialVersionUID =-empty; Socket s = null; JLabel label_shang = new JLabel (); JLabel label_xia = new JLabel (); JTextField tf = new JTextField (38); JTextArea ta = new JTextArea (15, 50); JButton button = new JButton (); public ChatClientFrame2 () {setBounds (200,200,500,400 ); setTitle ("client chat tool -- 0.4"); // large window layout, divided into three rows and one column, add three panels to the pBasic panel: shang zhong xia JPanel pBasic = new JPanel (); pBasic. setLayout (new BorderLayout (); // if this is not set, the default Layout mode is setContentPane (pBasic). // you can place the panel in the window. Do not remember to use this. keyword: JPanel shang = new JPanel (); JPanel zhong = new JPanel (); JPanel xia = new JPanel (); // set the size of the JPanel shang. setSize (470, 25); zhong. setSize (470,180); xia. setSize (470, 40); pBasic. add (shang, BorderLayout. NORTH); pBasic. add (zhong, BorderLayout. CENTER); pBasic. add (xia, BorderLayout. SOUTH); shang. setBackground (Color. red); zhong. setBackground (Color. yellow); xia. setBackground (Color. blue);/** three panels, with a tag "chat record" in the top, a text field in the middle, and * bottom divided into left-right -- respectively put the tag "input information", text Box and "send" button */la Bel_shang.setText ("Chat History"); shang. add (label_shang); ta. setLineWrap (true); // automatically wrap JScrollPane scroll = new JScrollPane (ta); // Add a scroll bar so that no rows are added. add (scroll); label_xia.setText ("input information"); xia. add (label_xia, BorderLayout. WEST);/** added the function to listen to events in the window. When the window is opened, set the cursor focus in the tf text domain */this. addWindowListener (new WindowAdapter () {@ Override public void windowOpened (invalid wevent e) {tf. requestFocus () ;}}); xia. add (tf, BorderLa Yout. CENTER); button. setText ("send"); xia. add (button, BorderLayout. EAST);/** added the "send" button function, and added the carriage return function. The Listener is the same. * internal class implementation is used, to improve code reusability */final class ShareListener implements ActionListener {@ Override public void actionreceivmed (ActionEvent e) {String taText = ta. getText (); String tfText = tf. getText () + "\ r \ n"; ta. setText (taText + tfText); tf. setText (""); // when you press ENTER or send a button, tfText is sent to the server try {// you can try to use the write in DataOutputStream UTF method // DataOutputStream ds = new DataOutputStream (s. getOutputStream (); // ds. writeUTF (tfText); // ds. flush (); // ds. close (); BufferedWriter bw = new BufferedWriter (new OutputStreamWriter (s. getOutputStream (), "UTF-8"); bw. write (tfText); bw. close () ;}catch (IOException e1) {// TODO Auto-generated catch block e1.printStackTrace () ;}} button. addActionListener (new ShareListener (); tf. addActionListener (New ShareListener (); // automatically adjust each panel pack () through compression; setdefaclocloseoperation (JFrame. EXIT_ON_CLOSE); // click the close button to exit the program at the same time. setVisible (true); // create a form and directly call connect server ();} /** Add a method to connect to the server */public void connect () {try {s = new Socket ("127.0.0.1", 8888); System. out. println ("connected! ");} Catch (UnknownHostException e) {// TODO Auto-generated catch block e. printStackTrace ();} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace () ;}} public static void main (String [] args) {// do not forget to create a form object. You can also use the generated object to call other methods, such as launchFrame () new ChatClientFrame2 ();}}
Before the problem is solved:
Package com. swift; import java. io. bufferedReader; import java. io. dataInputStream; import java. io. IOException; import java. io. inputStreamReader; import java.net. serverSocket; import java.net. socket; public class ChatServer {public static void main (String [] args) {try {ServerSocket ss = new ServerSocket (8888); for (;) {Socket s = ss. accept (); // when there is a connection, it is displayed for testing System. out. println ("a client connected success"); // you can try the readUTF method in DataInputStream // DataInputStream dis = new DataInputStream (s. getInputStream (); // String str = dis. readUTF (); // dis. close (); BufferedReader br = new BufferedReader (new InputStreamReader (s. getInputStream (), "UTF-8"); String str = br. readLine (); System. out. println (str) ;}} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace ();}}}
Demo process
Problem:
Java.net. SocketException: Socket is closed
If you do not close the stream
Delete this sentence bw. close ();
Yes, the program will not go wrong, but it will always be closed. You can execute this sentence when the client window is closed.
You can still send only one message but no error message. Why?
Check the program and find that each time you press ENTER or send, a message is sent, but the server does not display it. Because the client sends messages multiple times, the server only reads the message once, so display one,
The following code reads multiple times and displays multiple times:
Package com. swift; import java. io. bufferedReader; import java. io. IOException; import java. io. inputStreamReader; import java.net. serverSocket; import java.net. socket; public class ChatServer {public static void main (String [] args) {try {ServerSocket ss = new ServerSocket (8888); for (;) {Socket s = ss. accept (); // when there is a connection, it is displayed for testing System. out. println ("a client connected success"); BufferedReader br = new BufferedReader (new InputStreamReader (s. getInputStream (), "UTF-8"); // problem: the client sends messages multiple times, and the server reads the messages only once, so only once is output, the following method is not good for multiple outputs: String str = br. readLine (); System. out. println (str); String str1 = br. readLine (); System. out. println (str1); String str2 = br. readLine (); System. out. println (str2); String str3 = br. readLine (); System. out. println (str3) ;}} catch (IOException e) {e. printStackTrace ();}}}