您的位置:首页 > 理论基础 > 计算机网络

Java Socket 编程——多线程网络聊天程序

2008-04-22 23:30 543 查看
本文作者:longlongago     博客地址:http://blog.csdn.net/longlongago2000
用java进行网络编程确实很方便,很容易上手。这几天用java进行socket编程,收获不少。

首先,进行服务端的编程,作为服务端,编程主要按下面几个步骤进行:


// 1. 创建socket


            ServerSocket ss = new ServerSocket(PortNumber);


            Socket s = ss.accept(); //监听器,产生阻塞,直到有连接才停止阻塞。 




            // 2. 打开输入流、输出流


            OutputStream os = s.getOutputStream();


            BufferedOutputStream bos = new BufferedOutputStream(os);


            InputStream is = s.getInputStream(); 




            // 3. 根据一定的协议读写数据


            // 服务器 --> 客户


//            os.write("Hello,I am Server!".getBytes());


            bos.write("Hello,I am Server!".getBytes());


            bos.flush(); //注意!! 




            // 服务器 <-- 客户


            byte[] buf = new byte[100];


            int len = is.read(buf);


            System.out.println(new String(buf, 0, len)); 




            // 4. 关系流和Socket


//            os.close();


            bos.close();


            is.close();


            s.close();


            ss.close(); 





 

作为客户端则分为下面几个步骤,其实和服务端差不多,只是少了用ServerSocket进行监听。


// 1. 创建socket


            Socket s = new Socket(InetAddress.getByName("localhost"),


                    PortNumber);


            // 2. 打开输入流、输出流


            OutputStream os = s.getOutputStream();


            InputStream is = s.getInputStream(); 




            // 3. 根据一定的协议读写数据


            // 服务器 --> 客户


            byte[] buf = new byte[100];


            int len = is.read(buf);


            System.out.println(new String(buf, 0, len));


            // 服务器 <-- 客户


            os.write("Hello,I am Client!".getBytes()); 




            // 4. 关系流和Socket


            os.close();


            is.close();


            s.close(); 





上面这些只是一个单线程的服务端->客户端的程序,只能进行一次通讯,多次通讯将被告知无法连接。

这时,我们就需要用到进程Thread进行编程,将其改造成多线程聊天程序,可以同时进行多客户端的连接与发送信息。

代码如下:


//Server.java 




import java.awt.*;


import java.net.*;


import java.io.*; 






public class Server extends Thread ...{


    ServerSocket skt; 




    Socket Client[]=new Socket[10];;


    Socket Client1=null; 




    int i = 0; 




    TextArea in; 




    int port,k=0,l=0; 




    //BufferedReader theInputStream; 




    PrintStream theOutputStream; 




    //String readin; 




    Face chat; 






    public Server(int port, Face chat) ...{




        try ...{


            this.port = port;


            skt = new ServerSocket(port);


            this.chat = chat;




        } catch (IOException e) ...{


            chat.ta.append(e.toString());


        }


    } 






    public void run() ...{ 




        chat.ta.append("等待连线......"); 






        while (true) ...{


            //System.out.print(""+i+" ");




            try ...{


             






                Client[k] = skt.accept(); /**//* 接收客户连接 */




                //当有客户端连接时就新建一个子线程


                






                if (i < 2) ...{


                    ServerThread server[] = new ServerThread[10];


                     server[k]= new ServerThread(Client[k], this.chat, i);


                     l=server.length;


                     server[k].start();


                    chat.ta.append("客户端" + Client[k].getInetAddress() + "已连线 ");




                    /**//*theInputStream = new BufferedReader(new InputStreamReader(Client


                            .getInputStream()));*/


                    //for(int j=0;j<server.length;j++)


                    theOutputStream = new PrintStream(server[k].getClient().getOutputStream());


                    i = server[k].getI();


                    k++;




                } else ...{


                    //theOutputStream = new PrintStream(null);


                } 






            } catch (SocketException e) ...{


                //chat.ta.append("连线中断! "); 




                //chat.clientBtn.setEnabled(true);


                //chat.serverBtn.setEnabled(true);


                //chat.tfaddress.setEnabled(true);


                //chat.tfport.setEnabled(true);


                //try { 




                    //skt.close();


                    //Client.close();


                //} catch (IOException err) {


                //    chat.ta.append(err.toString());


                //}




            } catch (IOException e) ...{


                chat.ta.append(e.toString());


            }


        } 




    } 






    public void dataout(String data) ...{


        //for(int j=0;j<l;j++)


        theOutputStream.println(data);


    }









class ServerThread extends Thread ...{


    ServerSocket skt; 




    Socket client; 




    TextArea in; 




    int port; 




    int i; 




    BufferedReader theInputStream; 




    PrintStream theOutputStream; 




    String readin; 




    Face chat; 




//服务端子线程 






    public ServerThread(Socket s, Face chat, int i) ...{


        this.i = ++i;


        client= s;


        //this.port = port;


        //skt = new ServerSocket(port);


        this.chat = chat; 




    } 






    public int getI() ...{


        return this.i;


    }




    public Socket getClient() ...{


        return this.client;


    }




    public void run() ...{ 




        //chat.ta.append("等待连线......"); 






        try ...{


            //Client = skt.accept(); /* 接收客户连接 */ 




            //chat.ta.append("客户端" + Client.getInetAddress() + "已连线 ");


            theInputStream = new BufferedReader(new InputStreamReader(client


                    .getInputStream()));


            theOutputStream = new PrintStream(Client.getOutputStream()); 






            while (true) ...{


                readin = theInputStream.readLine();


                chat.ta.append(readin + " ");


            } 






        } catch (SocketException e) ...{


            chat.ta.append("连线中断! "); 




            chat.clientBtn.setEnabled(true);


            chat.serverBtn.setEnabled(true);


            chat.tfaddress.setEnabled(true);


            chat.tfport.setEnabled(true);




            try ...{


                i--;


                skt.close();


                client.close();




            } catch (IOException err) ...{


                chat.ta.append(err.toString());


            }




        } catch (IOException e) ...{


            chat.ta.append(e.toString());


        }


    } 






    public void dataout(String data) ...{


        theOutputStream.println(data);


    }







//Client.java 




import java.net.*;


import java.io.*;


import javax.swing.Timer;




class Client extends Thread ...{


    Socket skt;


    InetAddress host;


    int port; 




    BufferedReader theInputStream;


    PrintStream theOutputStream;


    String readin; 




    Face chat; 






    public Client(String ip, int p, Face chat) ...{




        try ...{


            host = InetAddress.getByName(ip);


            port = p;


            this.chat = chat;




        } catch (IOException e) ...{


            chat.ta.append(e.toString());


        }


    } 






    public void run() ...{




        try ...{


            chat.ta.append("尝试连线......"); 




            skt = new Socket(host, port);


            chat.ta.append("连线成功 "); 




            theInputStream = new BufferedReader(new InputStreamReader(skt


                    .getInputStream())); 




            theOutputStream = new PrintStream(skt.getOutputStream());


            //Timer myTimer = new Timer();




            while (true) ...{


                readin = theInputStream.readLine();


                chat.ta.append(readin + " ");


            }




        } catch (SocketException e) ...{


            chat.ta.append("连线中断! ");


            chat.clientBtn.setEnabled(true);


            chat.serverBtn.setEnabled(true);


            chat.tfaddress.setEnabled(true);


            chat.tfport.setEnabled(true);




            try ...{


                skt.close();




            } catch (IOException err) ...{


                chat.ta.append(err.toString());


            }




        } catch (IOException e) ...{


            chat.ta.append(e.toString());


        }


    } 






    public void dataout(String data) ...{


        theOutputStream.println(data);


    }







//软件界面,进行按键监听调用。




//face.java 




import java.awt.*;


import java.awt.event.*; 






public class Face extends Frame ...{




    /** *//**


     * 


     */


    private static final long serialVersionUID = 1L;


    Button clientBtn, serverBtn;


    TextArea ta;


    TextField tfaddress, tfport, tftype;


    int port;


    Client client;


    Server server;


    boolean iamserver;


    static Face frm; 






    public Face() ...{


        clientBtn = new Button("客户端");


        serverBtn = new Button("服务器");


        ta = new TextArea("", 10, 50, TextArea.SCROLLBARS_BOTH);


        tfaddress = new TextField("192.168.1.104", 20);


        tfport = new TextField("2000");


        tftype = new TextField(50); 




        tftype.addKeyListener(new TFListener());


        ta.setEditable(false); 




        setLayout(new FlowLayout());


        add(tfaddress);


        add(tfport);


        add(clientBtn);


        add(serverBtn);


        add(ta);


        add(tftype);


        setSize(400, 300);


        setTitle("我的聊天室");


        this.setVisible(true); 






        clientBtn.addActionListener(new ActionListener() ...{




            public void actionPerformed(ActionEvent e) ...{ 




                port = Integer.parseInt(tfport.getText()); 




                client = new Client(tfaddress.getText(), port, frm); 




                client.start(); 




                tfaddress.setEnabled(false);


                tfport.setEnabled(false);


                serverBtn.setEnabled(false);


                clientBtn.setEnabled(false);


            }


        }); 






        serverBtn.addActionListener(new ActionListener() ...{




            public void actionPerformed(ActionEvent e) ...{ 




                port = Integer.parseInt(tfport.getText()); 




                server = new Server(port, frm); 




                server.start(); 




                iamserver = true;


                tfaddress.setText("成为服务器"); 




                tfaddress.setEnabled(false);


                tfport.setEnabled(false);


                serverBtn.setEnabled(false);


                clientBtn.setEnabled(false);


            }


        }); 






        addWindowListener(new WindowAdapter() ...{




            public void windowClosing(WindowEvent e) ...{


                System.exit(0);


            }


        }); 




    } 






    public static void main(String args[]) ...{


        frm = new Face();


    } 






    private class TFListener implements KeyListener ...{




        public void keyPressed(KeyEvent e) ...{ 






            if (e.getKeyCode() == KeyEvent.VK_ENTER) ...{ 




                ta.append(">" + tftype.getText() + " "); 




                if (iamserver)


                    server.dataout(tftype.getText());


                else


                    client.dataout(tftype.getText()); 




                tftype.setText("");


            }


        } 






        public void keyTyped(KeyEvent e) ...{


        } 






        public void keyReleased(KeyEvent e) ...{


        }


    }


}





转载请注明:本文作者:longlongago     博客地址:http://blog.csdn.net/longlongago2000

这个程序我限制了连接数,大家可以根据自己的需要进行修改。

欢迎和我交流:email liufeituo@163.com

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息