zoukankan      html  css  js  c++  java
  • J2SE网络编程之 TCP与UDP

    1.什么是TCP

          TCP(Transmission Control Protocol传输控制协议)是一种面向连接的可靠的基于字节流的通信协议,位于传输层。这三个特点中,面向连接就如同打电话,双方的电话必须保持连接状态才能通话;可靠就如同QQ上的视频,一方发送视频请求,另一方必须同意后才能建立视频连接,也可以说安全性好;基于字节流,继续看下文就行。TCP最重要的思想就是大名鼎鼎的“三次握手”:

    • 客户端向服务端发送请求报文;
    • 服务端收到后向客户端回复;
    • 客户端确认收到服务端的回复。

    三次握手完成后,客户端就与服务端建立了可靠的链接。

    2.什么是UDP

        UDP(User Datagram Protocol用户数据报协议),提供简单但不可靠的信息传送服务。很像生活中的写信或发邮件,不需要征得对方的同意,不需要与对方建立连接,就可以将数据发送出去,但是不能保证发送出去的数据能够确保无误地到达目的地。

    注意: 我们常用的ping命令就是基于UDP协议,telnet命令就是基于TCP协议。

    3.TCP Socket示例

    服务端示例:

    import java.io.*;
    import java.net.*;
    public class Server {    
        public static void main(String[] args) {
            InputStream is=null; 
            OutputStream os=null;
            try{
                ServerSocket ss=new ServerSocket(5566);         //创建服务器套接字并绑定到5566端口
                Socket s=ss.accept();
                is=s.getInputStream();
                os=s.getOutputStream();
                DataInputStream dis=new DataInputStream(is);
                DataOutputStream dos=new DataOutputStream(os);
                String message=null;
                if((message=dis.readUTF())!=null){              //接收并输出此连接的客户端发来的信息
                    System.out.println("Client:"+message);
                }
                dos.writeUTF("Hello, Client!");                //向此连接的客户端发送信息
                dis.close();
                dos.close();
                s.close();
            }catch(ConnectException ex){
                ex.printStackTrace();
            }catch(IOException ex){
                ex.printStackTrace();
            }
        }
    }

    客户端示例

    import java.io.*;
    import java.net.*;
    public class Client {
        public static void main(String[] args) {
            InputStream is=null;
            OutputStream os=null;
            try{
                Socket s=new Socket("127.0.0.1",5566);         //创建一个套接字并将其连接到127.0.0.1地址(本机)的5566端口
                is=s.getInputStream();
                os=s.getOutputStream();
                DataInputStream dis=new DataInputStream(is);
                DataOutputStream dos=new DataOutputStream(os);
                dos.writeUTF("Hello, Server!");               //向服务端发送信息
                String message=null;
                if((message=dis.readUTF())!=null){
                    System.out.println("Server:"+message);    //接收并输出服务端发来的信息
                }
                dis.close();
                dos.close();
                s.close();            
            }catch(ConnectException ex){
                ex.printStackTrace();
            }catch(IOException ex){
                ex.printStackTrace();
            }
        }
    }

    整个连接和交互的过程如下图:

        执行时,先启动服务端,服务端创建服务器套接字ServerSocket并绑定到指定的端口,当执行到Socket s=ss.accept()时,会产生“阻塞”(即让程序暂时停留在此处),但客户端启动,创建套接字Socket并向指定地址的指定端口发送请求时,ServerSocket接受服务端的请求并返回客户端的socket实例,与之建立连接。socket原意为插座,还真的挺形象的,整个过程就如同把客户端的插头插到服务端的插座上,就建立起了通道。通信完毕后,双方都关闭连接。

        Socket的getInputStream()方法可以获得网络连接输入,返回此套接字的字节输入流对象;getOutputStream()方法返回此套接字的字节输出流对象,用于向连接对象写入数据。这里体现了上文中TCP的第三个特点“基于字节流”。

    4.UDP示例

    服务端Demo

    import java.net.*;
    class UDPServer{
        public static void main(String[] args)throws Exception{
            //接收信息
            DatagramSocket  server = new DatagramSocket(5050);
            byte[] recvBuf = new byte[1000];
            DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length);
            server.receive(recvPacket);
            String recvStr = new String(recvPacket.getData() , 0 , recvPacket.getLength());
            System.out.println("What server has received is:" + recvStr);
            
            //发送信息
            int port = recvPacket.getPort();
            InetAddress addr = recvPacket.getAddress();
            String sendStr = "Hello ! I'm Server";
            byte[] sendBuf = new String("Hello Client! I'm Server!").getBytes();    
            DatagramPacket sendPacket 
                = new DatagramPacket(sendBuf , sendBuf.length , addr , port );
            server.send(sendPacket);
            server.close();
        }
    }

    客户端Demo

    import java.net.*;
    class UDPClient{
        public static void main(String[] args)throws Exception{
            //发送信息
            DatagramSocket client = new DatagramSocket();       
            byte[] sendBuf=new String("Hello Server! I'm Client").getBytes();       
            InetAddress addr = InetAddress.getByName("127.0.0.1");
            int port = 5050;
            DatagramPacket sendPacket 
                = new DatagramPacket(sendBuf ,sendBuf.length , InetAddress.getByName("127.0.0.1") , port);
            client.send(sendPacket);
            
            //接收信息
            byte[] recvBuf = new byte[100];
            DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length);
            client.receive(recvPacket);
            String recvStr = new String(recvPacket.getData() , 0 ,recvPacket.getLength());
            System.out.println("What client has received is:" + recvStr);
            client.close();
        }
    }

    整个流程如下图:


          服务端启动后,准备一个包含字节数组buf的数据报包DatagramPacket用于接收客户端发来的数据报,客户端启动后,将目的地址、端口、发送内容等信息封装在DatagramPacket中,通过DatagramSocket的send()方法发往目的地(服务端),服务端将接收到的数据报放在DatagramPackage中。服务端向客户端发送数据报的过程亦然。

    5.总结

         文章前面说了TCP三次握手,客户端发送请求、服务端接受请求并返回确认信息,客户端收到确认信息后再发送确认收到确认信息,简单的三个步骤,过程却非常复杂(而且TCP断开连接时还需要四次挥手)。因为UDP协议不需要连接的过程,所以它的效率高,速度快,同时也因如此,UDP的可靠性不如TCP高。

  • 相关阅读:
    201871010125 王玉江 实验三 软件工程结对项目
    201871010125-王玉江 实验二 个人项目—《背包问题》项目报告
    201871010125 王玉江 实验一 软件工程准备—软件工程初步认识
    201871010125-王玉江《面向对象程序设计(java)》第十五周学习总结
    201871010125 王玉江《面向对象程序设计(java)》第十三周学习总结
    201871010125 王玉江 《面向对象程序设计(Java)》第八周实验总结
    201871010125 王玉江 《面向对象程序设计(java)》 第四周学习总结
    201871010125王玉江第二十周总结
    第一次作业
    【 D3.js 入门系列 — 0 】 简介和安装
  • 原文地址:https://www.cnblogs.com/zhulongchao/p/4581744.html
Copyright © 2011-2022 走看看