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

Java Tcp Socket聊天系统模型

2013-07-16 10:39 375 查看
Tcp Socket是面向连接的,所以Server端的accept()方法,一直等着客户端的连接,如果连接成功,则两者进行通信,这种是同步的,因为accept()一直在那儿等着,时刻的等着,实际中的聊天系统是采用异步方式,当有请求的时候就调用accept()方法,没有请求的时候该做什么就做什么去,不需要在那儿等着,不浪费资源,一种异步的方式。这个例子只是为了学习线程而准备的。 
端口有TCP端口和UDP端口两种,端口号都是从0到65535,TCP端口在3层,UDP不是四层就是7层 TCP和UDP的协议也不相同,TCP比UDP安全,更多TCP和UDP区别上google,baidu。 

服务器端编码 

Java代码  


import java.io.BufferedReader;  

import java.io.IOException;  

import java.io.InputStreamReader;  

import java.io.PrintStream;  

import java.net.ServerSocket;  

import java.net.Socket;  

import java.util.StringTokenizer;  

import java.util.Vector;  

  

/** 

 * 服务器端编码 

 * @author 欧阳平 2009-3-17  

 */  

public class ChatServer {  

    static int port = 5566;//端口号  

    static Vector<Client> clients = new Vector<Client>(10);//存储连接客户信息  

    static ServerSocket server = null; //建立服务器socket  

    static Socket socket = null; //套接字连接  

    /** 

     * Constructs 

     */  

    public ChatServer() {  

        try {  

            System.out.println("Server start...");  

            server  = new ServerSocket(port); //初始化服务器套接字  

            while (true) {  

                socket = server.accept(); //等待连接  

                System.out.println(socket.getInetAddress()+"连接\n");//得到客户机地址  

                Client client = new Client(socket); //实例化一个客户线程(其中线程Client中有Socket,这里的的Socket只是起个过度作用)  

                //  

                clients.add(client);//增加客户线程到向量中  

                client.start();//启动线程  

                notifyChatRoom(); //监视聊天室连接变化  

            }  

        } catch (Exception ex) {  

            ex.printStackTrace();//输出出错信息  

        }  

    }  

      

    public static void notifyChatRoom() { //监视客户端线程  

        StringBuffer newUser = new StringBuffer("newUser");  

        for (int i = 0; i < clients.size(); i++) {  

            Client c = (Client)clients.elementAt(i);  

            newUser.append(":"+c.name); //客户端姓名字符串  

        }  

        sendClients(newUser);//发送信息到客户端  

    }  

      

    public static void sendClients(StringBuffer message) {  

        for (int i= 0 ; i < clients.size(); i++) {  

            Client client = (Client)clients.elementAt(i);//分别得到每个客户端的连接  

            client.send(message);//发送信息  

        }  

    }  

      

    public void closeAll() { //关闭所有连接  

        while (clients.size() > 0 ) { //遍历整个Vector  

            Client client = (Client) clients.firstElement(); //得到一个客户端  

            try {  

                client.socket.close();  

            } catch(IOException ex) {  

                ex.printStackTrace(); // 输出错误信息  

            }  

            clients.removeElement(client); //移出客户端  

        }  

    }  

      

    public static void disconnect(Client c) {// 断开客户端  

        try {  

            System.err.println(c.ip+"断开连接\n");  

        } catch (Exception ex) {  

            ex.printStackTrace();  

        }  

        clients.removeElement(c);  

        c.socket = null;  

    }  

      

      

    /** 

     * main方法 

     * @param args 

     */  

    public static void main(String[] args) {  

        new ChatServer();  

  

    }  

    class Client extends Thread {  

        Socket socket;//连接端口  

        String name ;//用户姓名  

        String ip; //客户端ip地址  

        BufferedReader reader;//输入流  

        PrintStream ps;//输出流  

        public Client(Socket s) {  

            socket = s;  

            try {  

                reader = new BufferedReader(new InputStreamReader(s.getInputStream()));//得到输入流  

                ps = new PrintStream(s.getOutputStream());//得到输出流  

                String info = reader.readLine();//读取接收到的信息  

                StringTokenizer stinfo = new StringTokenizer(info,":"); //分解字符串  

                String head = stinfo.nextToken(); //获取关键字  

                System.out.println(stinfo.toString());  

                System.out.println(head);  

                if (stinfo.hasMoreTokens()){  

                    name = stinfo.nextToken() ;//获取用户名  

                }  

                if (stinfo.hasMoreTokens()) {  

                    ip = stinfo.nextToken(); //获取IP地址  

                }  

            } catch (IOException ex) {  

                ex.printStackTrace();  

            }  

            System.out.println(name);  

            System.out.println(ip);  

        }  

          

        public void send (StringBuffer msg) {  

            ps.println(msg); //输出信息  

            ps.flush();  

        }  

        public void run() {  

            while (true) {  

                String line = null;  

                try {  

                      

                    line = reader.readLine();  

                    System.out.println("line:"+line);  

                      

                } catch (IOException ex) {  

                    ex.printStackTrace(); //输出错误信息  

                    ChatServer.disconnect(this);//断开连接  

                    ChatServer.notifyChatRoom();//更新信息  

                    return ;  

                }  

                if (line == null) { //客户离开  

                    ChatServer.disconnect(this);  

                    ChatServer.notifyChatRoom();  

                    return ;  

                }  

                StringTokenizer st = new StringTokenizer(line,":");//分解字符串  

                String keyword = st.nextToken();  

                if (keyword.equals("MSG")) { //发送来的聊天信息  

                    StringBuffer msg = new StringBuffer("MSG:");  

                    msg.append(name); //在信息上增加用户名  

                    msg.append(st.nextToken("\0\n"));  

                    ChatServer.sendClients(msg);//发送聊天语句到各个客户端  

                    System.out.println(msg);  

                } else if (keyword.equals("quit")) { //退出命令  

                    ChatServer.disconnect(this); //断开连接  

                    ChatServer.notifyChatRoom(); //刷新信息  

                }  

            }  

        }  

    }  

      

}  

//客户端编码 

Java代码  


import java.awt.BorderLayout;  

import java.awt.Button;  

import java.awt.Color;  

import java.awt.Label;  

import java.awt.TextArea;  

import java.awt.TextField;  

import java.awt.event.ActionEvent;  

import java.awt.event.ActionListener;  

import java.io.BufferedReader;  

import java.io.IOException;  

import java.io.InputStreamReader;  

import java.io.PrintStream;  

import java.net.InetAddress;  

import java.net.Socket;  

import java.util.StringTokenizer;  

  

import javax.swing.JFrame;  

import javax.swing.JOptionPane;  

import javax.swing.JPanel;  

  

/** 

 * 基于Socket网络聊天程序 客户端编码 

 * @author 欧阳平 2009-3-17  

 */  

public class ChatClient extends JFrame  implements ActionListener,Runnable{  

      

    TextField tfName = new TextField(15);//姓名输入文本域  

    Button btConnect = new Button("连接");//连接按钮  

    Button btDisconnect = new Button("断开连接");//断开连接按钮  

    TextArea tfChat = new TextArea(8,27);//显示聊天信息文本域  

    Button btSend = new Button("发送");  

    TextField tfMessage = new TextField(30);//聊天输入  

    java.awt.List list1  = new java.awt.List(9);//显示在线用户信息   

    Socket socket = null;//连接端口  

    PrintStream ps = null;//输出流  

    Listen listen = null;  

    //监听线程类  

    class Listen extends Thread {  

        BufferedReader reader;  

        PrintStream ps;  

        String cname;  

        Socket socket;  

        ChatClient chatClient;  

        public Listen(ChatClient client,String name,Socket socket) {  

            try {  

                this.chatClient = client;  

                 this.socket = socket;  

                 this.cname = name;  

                 reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  

                 ps = new PrintStream(socket.getOutputStream());  

            } catch (IOException e) {  

                e.printStackTrace();  

            }  

        }  

        public void run() {  

            while (true) {  

                String line=null ;  

                try {  

                line = reader.readLine(); //读取数据流  

                System.out.println("客户端:"+line);  

                  

            }catch (IOException ex) {  

                ex.printStackTrace();  

                ps.println("quit");; //断开连接  

                return;  

            }  

            StringTokenizer stinfo = new StringTokenizer(line,":"); //分解字符串  

            String keyword = stinfo.nextToken();  

            if (keyword.equals("MSG")) {  

                chatClient.tfChat.append(line+"\n");  

            }  

            else if (keyword.equals("newUser")){  

                chatClient.list1.clear();  

                chatClient.list1.add("users", 0);  

                int i = 1;  

                while (stinfo.hasMoreTokens()) {  

                    chatClient.list1.add(stinfo.nextToken(), i++);  

                }  

            }  

        }  

          

      }  

    }  

    public void actionPerformed(ActionEvent e) {  

        try{  

            if(e.getSource()==btConnect) { //点击连接按钮  

                if (socket == null) {  

                    socket = new Socket(InetAddress.getLocalHost(),5566);//实例化一个套接字  

                    ps = new PrintStream(socket.getOutputStream());//获取输出流,写入信息  

                    StringBuffer info = new StringBuffer("info:");  

                    String userinfo = tfName.getText()+":"+InetAddress.getLocalHost().toString();  

                    ps.println(info.append(userinfo));//输出信息  

                    ps.flush();  

                    listen = new Listen(this,tfName.getText(),socket);  

                    listen.start();  

                }  

            } else if (e.getSource() == btDisconnect) { //点击断开连接按钮  

                disconnect();  

            } else if (e.getSource() == btSend) { //点击发送按钮  

                if (socket != null) {  

                    StringBuffer msg = new StringBuffer("MSG:");  

                    String msgtxt = new String(tfMessage.getText());  

                    ps.println(msg.append(msgtxt));//发送信息  

                    ps.flush();  

                } else {  

                    JOptionPane.showMessageDialog(this, "请先连接!", "提示", 1);  

                }  

            }  

              

        } catch (Exception ex) {  

            ex.printStackTrace();//输出错误信息  

        }  

    }  

    public void disconnect() { //断开连接方法  

        if (socket != null) {  

            ps.println("quit");//发送信息  

            ps.flush();  

              

            socket = null;  

            tfName.setText("");  

        }  

    }  

      

      

      

      

      

      

  

      

    public ChatClient(Socket socket) {  

          

          

        this.setLayout(new BorderLayout());  

          

        JPanel panel1 = new JPanel();  

        Label label = new Label("姓名");  

        panel1.setBackground(Color.orange);  

        panel1.add(label);  

        panel1.add(tfName);  

        panel1.add(btConnect);  

        panel1.add(btDisconnect);  

        this.add(panel1,BorderLayout.NORTH);  

          

        JPanel panel2 = new JPanel();  

        panel2.add(tfChat);  

        panel2.add(list1);  

        this.add(panel2,BorderLayout.CENTER);  

          

        JPanel panel3 = new JPanel();  

        Label label2 = new Label("聊天信息");  

        panel3.add(label2);  

        panel3.add(tfMessage);  

        panel3.add(btSend);  

        this.add(panel3,BorderLayout.SOUTH);  

          

        this.setBounds(50,50,400,350);  

        this.setVisible(true);  

          

        btConnect.addActionListener(this);  

        btDisconnect.addActionListener(this);  

        btSend.addActionListener(this);  

          

    }  

      

    /** 

     * @param args 

     */  

    public static void main(String[] args) {  

        ChatClient client = new ChatClient(new Socket());  

        System.out.println(client.socket);  

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