socket群聊

服务端:

package Inernet;

import java.awt.BorderLayout;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;

public class fffffff extends JFrame {

    private JPanel contentpanel;
    private JTextArea message;
    private ServerSocket server;
    private ArrayList<Socket> client=new  ArrayList<Socket>();  //存放scoket
    
    private PrintWriter out;
    private Socket s;
    /*
     * launch the main
     */
    public static void main(String[] agrs)
    {
        fffffff frame=new fffffff();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.createThread();
    }
    
    private void createThread()
    {
        s=new Socket();
        try {
            server=new ServerSocket(6000);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        while(true)
        {
            try {
                message.append("等待连接...\n");
                s=server.accept();
                message.append("连接成功...."+s+"\n");
                client.add(s);
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                        
                             Scanner in=new Scanner(s.getInputStream());
                        while(s.isConnected())
                        {
                            
                            String str=in.nextLine();
//                            System.out.println(str);
                            message.append(str);
                            for(Socket i:client)      //关键代码,循环创建socket的输出流,将数据输出到每个窗口
                            {
                                
                                    out=new PrintWriter(i.getOutputStream(),true);
                                    out.println(str);
                                    out.flush();
                            }
                        }
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                    }
                }).start();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    /*
     * create the frame
     */
    public fffffff()
    {
        contentpanel=new JPanel();
        setContentPane(contentpanel);
        contentpanel.setBorder(new EmptyBorder(5,5,5,5));
        setBounds(300, 300, 300, 300);
        contentpanel.setLayout(new BorderLayout());
        setTitle("服务端");
        JScrollPane jscrollpanel=new JScrollPane();
        contentpanel.add(jscrollpanel,BorderLayout.CENTER);
        message=new JTextArea();
        jscrollpanel.setViewportView(message);
        
    }
}




客户端:
package Inernet;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import javax.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;
import javax.swing.border.EmptyBorder;

public class ffff extends JFrame{

    private JPanel contentpanel;
    private JTextField name;
    private JTextArea message;
    private JTextField send_message;
    private JButton send;
    private Socket client;
    private Scanner in;
    private PrintWriter out;
    /*
     * launch the main
     */
    public static void main(String[] agrs)
    {
        ffff frame=new ffff();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.createClient();
    }
    private void createClient()
    {
        try {
            client=new Socket("127.0.0.1",6000);
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    while(client.isConnected())
                    {
                        try {
                            in=new Scanner(client.getInputStream());
                            String str=in.nextLine()+"\n\r";
                            message.append(str);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    /*
     * create the frame
     */
    public ffff()
    {
        setTitle("客户端");
        contentpanel=new JPanel();
        setContentPane(contentpanel);
        contentpanel.setBorder(new EmptyBorder(5,5,5,5));
        setBounds(300, 300, 350, 400);
        contentpanel.setLayout(new BorderLayout());
        
        JPanel toppanel=new JPanel();
        contentpanel.add(toppanel,BorderLayout.NORTH);
        toppanel.add(new JLabel("昵称"));
        name=new JTextField(20);
        toppanel.add(name);
        JScrollPane jscrollpanl=new JScrollPane();
        contentpanel.add(jscrollpanl,BorderLayout.CENTER);
        message=new JTextArea();
        jscrollpanl.setViewportView(message);
        JPanel bottompanel =new JPanel();
        contentpanel.add(bottompanel,BorderLayout.SOUTH);
        bottompanel.add(new JLabel("发送:"));
        send_message=new JTextField(15);
        bottompanel.add(send_message);
        send=new JButton("发送");
        bottompanel.add(send);
        send.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                try {
                    out=new PrintWriter(client.getOutputStream());
                    String str=name.getText()+":"+send_message.getText();
                    out.println(str);
//                    System.out.println(str);
                    out.flush();
                    send_message.setText("");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
            }
        });
        
    }
}

在写代码途中遇到一个问题就是 Scanner in这个变量 在服务器中只创建里一个变量结果在创建多个线程的时候,就被赋值给最新创建的进程,老的线程就卡死了,解决方法要在每一个Thread 中创建一个Scanner 使其线程独有化


;