Java TCP通信概念及实例

来源:互联网 发布:广东十一选五遗漏数据 编辑:程序博客网 时间:2024/06/05 21:01
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()+"\n");            } catch (Exception e) {                // TODO: handle exception            }        }    }        public void Create_Socket(InetAddress ip,int port){        ShowArea.append("正在尝试连接到服务端…… ……"+"\n");        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);    }                }

示例效果:

原创粉丝点击