首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

100分Socket网络编程

2012-07-28 
100分求助Socket网络编程现在想做一个类似于QQ群功能程序,做的过程遇到很多问题Server类只需要实现接受每

100分求助Socket网络编程
现在想做一个类似于QQ群功能程序,做的过程遇到很多问题
Server类只需要实现接受每个client类的传出的信息,并且打印在自己的信息板上,
然后将接受的信息发送给每个client
也就是说,每个client能看到彼此发送的信息,功能类似于QQ群
client的功能一是打印自己输出的信息,二是接受Server传过来的信息,打印出来
初学网络编程,欢迎拍砖
下面是代码
Server 类

Java code
package ex30;import javax.swing.*;import java.io.*;import java.io.IOException;import java.net.*;import java.util.*;public class Ex30_13Server extends JFrame{    private JTextArea jtaServer = new JTextArea();    private BufferedReader input;    private String sendMessage = "";    private ArrayList<Socket> socketArray = new ArrayList<Socket>();        public Ex30_13Server(){        jtaServer.setEditable(false);        add(new JScrollPane(jtaServer));        setTitle("MultiThreadServer");        setSize(700, 300);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setVisible(true);                try{            ServerSocket serverSocket = new ServerSocket(8000);                        while(true){                Socket socket = serverSocket.accept();                InetAddress inetAddress = socket.getInetAddress();                jtaServer.append(inetAddress.getHostName() + " connected " + new Date());                socketArray.add(socket);                                MutiUser mu = new MutiUser(socket);                mu.start();            }        }        catch(Exception ex){            ex.printStackTrace();        }    }    //     Define the thread class for send message    class SendTask implements Runnable{        public void run(){            try{                while(true){                    if(!sendMessage.isEmpty()){                        for(Socket socket : socketArray){  // 将接受的信息输出到每个客户端上                            PrintWriter outputToEachClient = new PrintWriter(socket.getOutputStream());                            outputToEachClient.println(sendMessage);                        }                        sendMessage = "";                    }                }            }            catch(Exception ex){                ex.printStackTrace();            }                    }    }            // Define the thread class for receive message    class ReceiveTask implements Runnable{        public void run(){            try{                while(true){                    String receiveMessage = input.readLine();                    if(!receiveMessage.isEmpty()){                        jtaServer.append(receiveMessage + "\n");                        sendMessage = receiveMessage;                    }                                    }            }            catch(IOException ex){                ex.printStackTrace();            }        }    }        class MutiUser extends Thread{        private Socket server;                public MutiUser(Socket server){            this.server = server;        }                public void run(){            try{                input = new BufferedReader(new InputStreamReader(server.getInputStream()));                new Thread(new SendTask()).start();                new Thread(new ReceiveTask()).start();            }            catch(Exception ex){                ex.printStackTrace();            }        }    }        public static void main(String[] args) {        // TODO 自动生成方法存根        new Ex30_13Server();    }}


client类
Java code
package ex30;import javax.swing.*;import ex30.Ex30_12Client.ReceiveTask;import ex30.Ex30_12Client.SendTask;import java.io.*;import java.awt.*;import java.awt.event.*;import java.net.*;public class Ex30_13Client extends JFrame{    private JLabel jlblName = new JLabel("Name");    private JLabel jlblText = new JLabel("Enter text");    private JTextField jtfName = new JTextField();    private JTextField jtfText = new JTextField();    private JTextArea jtaClient = new JTextArea();    private PrintWriter output;    private BufferedReader input;    private String sendMessage = "";        public Ex30_13Client(){        JPanel panel1 = new JPanel(new GridLayout(2, 1));        panel1.add(jlblName);        panel1.add(jlblText);                JPanel panel2 = new JPanel(new GridLayout(2, 1));        panel2.add(jtfName);        panel2.add(jtfText);                JPanel panel = new JPanel(new BorderLayout());        panel.add(panel1, BorderLayout.WEST);        panel.add(panel2, BorderLayout.CENTER);                setLayout(new BorderLayout());        add(panel, BorderLayout.NORTH);        add(jtaClient, BorderLayout.CENTER);        jtaClient.setEditable(false);                setTitle("Ex30_13Client");;        setSize(500, 300);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setLocationRelativeTo(null);        setVisible(true);                        jtfText.addKeyListener(new KeyAdapter(){            public void keyPressed(KeyEvent e){                if(e.getKeyCode() == KeyEvent.VK_ENTER){                    String text = jtfText.getText();                                        if(!text.isEmpty()){                        sendMessage = jtfName.getText() + ":" + text;                        output.println(sendMessage);                        output.flush();                        System.out.println(sendMessage);                        jtfText.setText("");                      }                }            }        });                try{            Socket socket = new Socket("localhost", 8000);            output = new PrintWriter(socket.getOutputStream());            input = new BufferedReader(new InputStreamReader(socket.getInputStream()));            new Thread(new SendTask()).start();            new Thread(new ReceiveTask()).start();        }        catch (Exception ex){            ex.printStackTrace();        }            }        class SendTask implements Runnable{        public void run(){            try{                while(true){                    if(!sendMessage.isEmpty()){                        jtaClient.append(sendMessage + "\n");                        sendMessage = "";                    }                }            }            catch(Exception ex){                ex.printStackTrace();            }        }    }        class ReceiveTask implements Runnable{        public void run(){            try{                while(true){                    String receiveMessage = input.readLine();                    jtaClient.append(receiveMessage + "\n");                }            }            catch(Exception ex){                ex.printStackTrace();            }        }    }                public static void main(String[] args) {        // TODO 自动生成方法存根        new Ex30_13Client();    }} 



[解决办法]
问题很多,主要是多线程数据同步的问题,建议你多看看这方面的书,学习使用java.util.concurrent包里的各种工具类。

尽量不要把代码都写在构造器里面,这是很不好的习惯。

[解决办法]
server 类改一下,关键是整体设计不太好


Java code
package ex40;import javax.swing.*;import java.io.*;import java.io.IOException;import java.net.*;import java.util.*;public class Ex30_13Server extends JFrame {    private JTextArea jtaServer = new JTextArea();    private String sendMessage = "";    private ArrayList<Socket> socketArray = new ArrayList<Socket>();    public Ex30_13Server() {        jtaServer.setEditable(false);        add(new JScrollPane(jtaServer));        setTitle("MultiThreadServer");        setSize(700, 300);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setVisible(true);        try {            ServerSocket serverSocket = new ServerSocket(8000);            while (true) {                Socket socket = serverSocket.accept();                InetAddress inetAddress = socket.getInetAddress();                jtaServer.append(inetAddress.getHostName() + " connected "                        + new Date());                socketArray.add(socket);                MutiUser mu = new MutiUser(socket);                mu.start();            }        } catch (Exception ex) {            ex.printStackTrace();        }    }    // Define the thread class for send message    class SendTask implements Runnable {        private MutiUser mu;        public SendTask(MutiUser mu) {            this.mu=mu;        }        public void run() {            try {                while (true) {                    if (!sendMessage.isEmpty()) {                        for (Socket socket : socketArray) { // 将接受的信息输出到每个客户端上                            PrintWriter outputToEachClient = new PrintWriter(                                    socket.getOutputStream());                            outputToEachClient.println(sendMessage);                        }                        sendMessage = "";                    }                }            } catch (Exception ex) {                ex.printStackTrace();            }        }    }    // Define the thread class for receive message    class ReceiveTask implements Runnable {        private MutiUser mu;                public ReceiveTask(MutiUser mu)        {            this.mu=mu;        }        public void run() {            try {                while (true) {                    String receiveMessage = mu.input.readLine();                    if (!receiveMessage.isEmpty()) {                        jtaServer.append(receiveMessage + "\n");                        sendMessage = receiveMessage;                    }                }            } catch (IOException ex) {                ex.printStackTrace();            }        }    }    class MutiUser extends Thread {        private Socket server;        private BufferedReader input;        public MutiUser(Socket server) {            this.server = server;        }        public void run() {            try {                input = new BufferedReader(new InputStreamReader(                        server.getInputStream()));                new Thread(new SendTask(this)).start();                new Thread(new ReceiveTask(this)).start();            } catch (Exception ex) {                ex.printStackTrace();            }        }    }    public static void main(String[] args) {        // TODO 自动生成方法存根        new Ex30_13Server();    }}
[解决办法]
闲来无事帮你改了改,服务器端改得多点,客户端基本没动,能完成你要的功能了

Java code
package ex30;import javax.swing.*;import java.io.*;import java.io.IOException;import java.net.*;import java.util.*;import java.util.concurrent.ConcurrentLinkedQueue;public class Ex30_13Server extends JFrame implements Runnable{    private JTextArea jtaServer = new JTextArea();    private BufferedReader input;    private String sendMessage = "";    private ConcurrentLinkedQueue<String> messageQueue = null;    private ArrayList<Socket> socketArray = new ArrayList<Socket>();        public Ex30_13Server(){        jtaServer.setEditable(false);        add(new JScrollPane(jtaServer));        setTitle("MultiThreadServer");        setSize(700, 300);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setVisible(true);        this.messageQueue = new ConcurrentLinkedQueue<String>();        new Thread(this).start();    }        @Override    public void run() {        ServerSocket serverSocket = null;        try{            serverSocket = new ServerSocket(8000);            new Thread(new broadcaster()).start();            while(true){                Socket socket = serverSocket.accept();                InetAddress inetAddress = socket.getInetAddress();                synchronized (socketArray){                    socketArray.add(socket);                }                new Thread( new UserInput(socket)).start();                synchronized (jtaServer) {                    jtaServer.append(inetAddress.getHostName() + " connected " + new Date()+ "\n");                }            }                    } catch(Exception ex){            ex.printStackTrace();        } finally {            try {                serverSocket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }        class broadcaster implements Runnable{        @Override        public void run() {            while (true){                if (!messageQueue.isEmpty()){                    synchronized (socketArray){                        try {                            String message = messageQueue.poll();                            for(Socket socket : socketArray){  // 将接受的信息输出到每个客户端上                                                PrintWriter outputToEachClient = new PrintWriter(socket.getOutputStream());                                            outputToEachClient.println(message);                                outputToEachClient.flush();                            }                        } catch (IOException e) {                                                            e.printStackTrace();                        }                    }                }            }            }    }        class UserInput implements Runnable {        private Socket socket;                        public UserInput(Socket socket){            this.socket = socket;                    }                @Override        public void run() {            try {                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                String inputLine = null;                while (true){                    while ((inputLine = in.readLine()) != null) {                        messageQueue.add(inputLine);                        jtaServer.append(inputLine+"\n");                    }                }            } catch (Exception e) {                //e.printStackTrace();            } finally {                try {                    socket.close();                    synchronized (socketArray){                        socketArray.remove(socket);                    }                    } catch (IOException e1) {                                        System.out.println("Can not close socket");                }            }        }    }        public static void main(String[] args) {        // TODO 自动生成方法存根        new Ex30_13Server();    }} 


[解决办法]
楼上的是正确的,改了几次楼主的代码,发现楼主对对象的使用存在些问题,可以学习
[解决办法]
只是为了服务监听放在单独的线程

热点排行