zoukankan      html  css  js  c++  java
  • Java TCP通信概念及实例

    TCP/UDP 协议

    通俗解释:

           TCP协议和UDP协议的区别类似于电话系统和邮政系统。

                  <1>TCP:类似于电话系统,建立双向的通信通道,确定连接,话音顺序接听

                  <2>UDP:类似于邮政系统,发送方将信件发送到正确的地址,但并不知道准确的邮路,大多数邮件到达了目的地,个别情况一些邮件会在路上丢失。邮件不保证顺序到达目的地。

    TCP套接字

           Socket

      客户端的通信套接字,可指定远端IP地址、端口进行连接通信,也可以通过方法获取已连接的socket的远端IP地址、端口,以及将此socket以字节输入流和输出流的形式返回,当与数据输入流和输出流绑定,便可实现客户端的网络通信。

      构造函数均为public修饰类型,如果创建socket时发生I/O错误,均抛出IOException异常。常用构造函数如下:

           Socket(InetAddress address,int port):创建一个socket并与规定的IP地址的指定的端口相连接。

           Socket(String host,int port):创建一个socket并与指定主机的指定端口连接。

           ServerSocket        

           服务器的通讯套接字,用来侦听客户端请求的连接,并为每个新连接创建一个socket对象,由此创建绑定此socket的输入流和输出流,与客户端实现网络通信。

       构造函数均为public修饰类型,如果创建socket时发生I/O错误,均抛出IOException异常。常用构造函数如下:

       ServerSocket(int port):在所给定的用来侦听的端口上建立一个服务器套接字。如果端口号为0,则在任意的空闲的端口上建立要给服务器套接字。外来连接请求的数量默认最大为50。

    多线程聊天室实例

    服务端Cilent

       创建ServerSocket并监听设置的端口,调用accpet()方法,直到找到对应的socket与之连接,创建一个线程为止服务。

       Launch the Application 部分为Java Swing的窗口部分。

    public class ServerCilent {
    
        private JFrame frmServer;
        private JTextField textField;
        private JTable table;
        private JLabel lblNewLabel;
        private JButton btnRefresh;
        private JButton btnListenstart;
        private SocketManager SocketArr=new SocketManager();
        
        //创建 Server端
            void getServer(int port)
            {
                try {
                    ServerSocket serverSocket=new ServerSocket(port);
                    System.out.println("已经开启服务端");
                    while(true)
                    {
                        Socket socket=serverSocket.accept();
                        new W_Thread(socket).start();
                        SocketArr.add(socket);
                        SocketArr.sendClientInfo();
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            
        class W_Thread extends Thread
        {
            Socket socket=null;
            private BufferedReader reader;
            private PrintWriter writer;
            public W_Thread(Socket socket)
            {
                this.socket=socket;
            }
            
            public void run()
            {
                try {
                    reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    writer=new PrintWriter(socket.getOutputStream(),true);
                    String msg;
                    while((msg=reader.readLine())!=null )
                    {
                        System.out.println(msg);
                        SocketArr.SendtoAll(msg);
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
                
            }
            
        }
        
    
        
        
        
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        ServerCilent window = new ServerCilent();
                        window.frmServer.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the application.
         */
        public ServerCilent() {
            initialize();
        }
    
        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            frmServer = new JFrame();
            frmServer.setResizable(false);
            frmServer.setTitle("ServerCilent");
            frmServer.setBounds(100, 100, 452, 371);
            frmServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frmServer.getContentPane().setLayout(null);
            
            JPanel panel = new JPanel();
            panel.setBorder(new TitledBorder(null, "DefaultSetting", TitledBorder.LEADING, TitledBorder.TOP, null, null));
            panel.setBounds(10, 10, 414, 66);
            frmServer.getContentPane().add(panel);
            panel.setLayout(null);
            
            JLabel lblPort = new JLabel("Port:");
            lblPort.setBounds(10, 25, 54, 15);
            panel.add(lblPort);
            
            textField = new JTextField();
            textField.setBounds(48, 22, 122, 21);
            panel.add(textField);
            textField.setColumns(10);
            
            btnListenstart = new JButton("Listen&Start");
            btnListenstart.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {
                    int port=Integer.parseInt(textField.getText());
                    ServerCilent serverCilent=new ServerCilent();
                    serverCilent.getServer(port);
                    textField.setEditable(false);
                    btnListenstart.setVisible(false);
                }
            });
            btnListenstart.setBounds(254, 21, 136, 23);
            panel.add(btnListenstart);
            
            
            JLabel label = new JLabel("在线人数:");
            label.setBounds(10, 298, 82, 15);
            frmServer.getContentPane().add(label);
            
            lblNewLabel = new JLabel(String.valueOf(SocketArr.size()));
            lblNewLabel.setBounds(75, 298, 54, 15);
            frmServer.getContentPane().add(lblNewLabel);
            
            btnRefresh = new JButton("Refresh");
            btnRefresh.setBounds(331, 298, 93, 23);
            frmServer.getContentPane().add(btnRefresh);
        }
    }

    多线程客户端Cilent

    创建Socket,并获取对应的输入输出流即可。

    public class Cilent implements Runnable{
    
        /*Swing*/
        private JFrame frmLogincilent;
        private JTextField IPAdress;
        private JTextField Port;
        private JTextField Nickname;
        private JTextField Sendinfo;
        private JButton Sumbit;
        private JTextArea ShowArea;
        private JButton Send;
        /*Stream*/
        private BufferedReader reader;
        private PrintWriter writer;
        
        
        
        @Override
        public void run(){
            while(true){
                try {
                    ShowArea.append(reader.readLine()+"
    ");
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }
        }
        
        public void Create_Socket(InetAddress ip,int port){
            ShowArea.append("正在尝试连接到服务端…… ……"+"
    ");
            try {
                Socket socket=new Socket(ip, port);
                ShowArea.append("聊天室已经准备好");
                frmLogincilent.setTitle("Ip:"+ip+"   Port:"+port+"   已连接在线");
                reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                writer=new PrintWriter(socket.getOutputStream(),true);
                new Thread(this).start();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
            
        
        
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        Cilent window = new Cilent();
                        window.frmLogincilent.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the application.
         */
        public Cilent() {
            initialize();
        }
    
        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            frmLogincilent = new JFrame();
            frmLogincilent.setResizable(false);
            frmLogincilent.setTitle("Cilent");
            frmLogincilent.setBounds(100, 100, 458, 532);
            frmLogincilent.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frmLogincilent.getContentPane().setLayout(null);
            
            JPanel panel = new JPanel();
            panel.setBorder(new TitledBorder(null, "Default Setting", TitledBorder.LEADING, TitledBorder.TOP, null, null));
            panel.setBounds(10, 10, 424, 84);
            frmLogincilent.getContentPane().add(panel);
            panel.setLayout(null);
            
            JLabel lblIpAdress = new JLabel("IP Adress:");
            lblIpAdress.setBounds(10, 20, 73, 15);
            panel.add(lblIpAdress);
            
            IPAdress = new JTextField();
            IPAdress.setBounds(82, 17, 142, 21);
            panel.add(IPAdress);
            IPAdress.setColumns(10);
            
            JLabel lblProt = new JLabel("Prot:");
            lblProt.setBounds(10, 48, 54, 15);
            panel.add(lblProt);
            
            Port = new JTextField();
            Port.setBounds(82, 45, 66, 21);
            panel.add(Port);
            Port.setColumns(10);
            
            JLabel lblNickname = new JLabel("NickName:");
            lblNickname.setBounds(170, 48, 73, 15);
            panel.add(lblNickname);
            
            Nickname = new JTextField();
            Nickname.setBounds(238, 45, 176, 21);
            panel.add(Nickname);
            Nickname.setColumns(10);
            
            Sumbit = new JButton("Lock&Login");
            Sumbit.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {
                        try {
                            /*Create Socket*/
                            String ipString=IPAdress.getText();
                            int port=Integer.parseInt(Port.getText());
                            String Name=Nickname.getText();
                            InetAddress ip=InetAddress.getByName(ipString);
                            Create_Socket(ip, port);
                            
                            /*Swing*/
                            IPAdress.setEditable(false);
                            Port.setEditable(false);
                            Nickname.setEditable(false);
                            Sumbit.setVisible(false);
                            
                        } catch (Exception e) {
                            // TODO: handle exception
                            JOptionPane.showMessageDialog(null, "invalid data");
                        }
                    }
                    
                    
                    
                
            });
            Sumbit.setBounds(272, 16, 142, 23);
            panel.add(Sumbit);
            
            ShowArea = new JTextArea();
            ShowArea.setBounds(10, 104, 424, 358);
            frmLogincilent.getContentPane().add(ShowArea);
            
            Sendinfo = new JTextField();
            Sendinfo.setBounds(10, 472, 330, 21);
            frmLogincilent.getContentPane().add(Sendinfo);
            Sendinfo.setColumns(10);
            
            Send = new JButton("Send");
            Send.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {
                    writer.println(Nickname.getText()+":"+Sendinfo.getText());
                    Sendinfo.setText("");
                }
            });
            Send.setBounds(349, 471, 85, 23);
            frmLogincilent.getContentPane().add(Send);
        }
    }

    Socket管理类

    继承ArrayList,并添加发送的方法SendtoAll(),以及显示当前连接数目的方法SendCilentInfo()

    public class SocketManager extends ArrayList{
        
        synchronized void add(Socket x)
        {
            super.add(x);
        }
        
        synchronized void remove(Socket x)
        {
            super.remove(x);
        }
        
        synchronized void SendtoAll(String str)
        {
            PrintWriter writer=null;
            Socket socket;
            for(int i=0;i<size();i++)
            {
                socket=(Socket)get(i);
                try {
                    writer=new PrintWriter(socket.getOutputStream(),true);
                    if(writer!=null)
                    {
                        writer.println(str);
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            
        }
        
        synchronized void sendClientInfo()
        {
            String info="当前位于聊天室的人数为"+size();
            System.out.println(info);
            SendtoAll(info);
        }
            
            
    }

    示例效果:

    作者:Rekent
    出处:http://www.cnblogs.com/rekent/
    本文版权归作者和博客园共有,欢迎转载、点赞,但未经作者同意必须保留此段申明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    452.用最少数量的箭引爆气球
    134.加油站
    Javascript
    spring-JDBC模板
    AOP注解方式ApsectJ开发
    AOP通知类型
    AOP的使用
    AOP相关术语
    AOP
    IOC注解详解
  • 原文地址:https://www.cnblogs.com/rekent/p/6920440.html
Copyright © 2011-2022 走看看