02 Socket网络编程

概述:

Socket又称为套接字,用于描述IP地址和端口,是一个通信链的句柄;

Socket是为网络编程提供的一种机制;

通信两端都有Socket,网络编程就是Socket之间的通信,数据在两个Socket之间通过IO流传输

学习Socket编程之前,先要了解网络通信的三i个要素,即IP端口号传输协议。

ip是设备在网络里面的地址。

端口号是用于标识进程的逻辑地址

  • 每个网络程序都会至少有一个逻辑端口
  • 用于标识进程的逻辑地址,不同进程的标识
  • 有效端口:0-65535,其中0-1024系统使用或保留端口

协议:主要有UDP协议和TCP协议

  • UDP协议是将数据源和目的封装成数据包,不需要建立连接,并且每个数据包的大小限制在64k,是一种不可靠协议,优点在于速度快
  • TCP协议是建立连接,并形成数据传输的通道;可以在连接中传输大量的数据;通过三次握手完成连接,是一种可靠协议,但效率较低

 

下面就围绕UDP和TCP这两种协议进行网络编程:

 1.UDP协议

  • 发送端执行步骤
  1. 创建发送端Socket对象
  2. 创建数据并打包
  3. 发送数据
  4. 释放资源

代码如下:

 

    public static void main(String[] args) throws Exception {
        //创建发送端Socket对象
        DatagramSocket socket = new DatagramSocket();
        //创建数据并打包
        //DatagramPacket(byte buf[], int length,  InetAddress address, int port)
        String message = "hello,UDP,I'm sender";
        byte[] bytes = message.getBytes();
        int length = bytes.length;
        InetAddress address = InetAddress.getByName("DESKTOP-KHNDCKQ");
        int port =8888;
        DatagramPacket p = new DatagramPacket(bytes,length,address,port);
        //发送数据
        socket.send(p);
        //释放资源
        socket.close();
    }

 

需要注意的是,发送端发送数据,需要指定目标ip或主机名,以及端口号。

 

 

  • 接收端执行步骤
  1. 创建接收端Socket对象
  2. 接收数据
  3. 解析数据
  4. 输出数据
  5. 释放资源

代码如下:

        //创建接收端对象
        DatagramSocket socket = new DatagramSocket(8888);
        //接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket data = new DatagramPacket(bytes,bytes.length);
        socket.receive(data);//阻塞
        //解析数据
        InetAddress address =  data.getAddress();//获取发送端IP
        byte[] receivedata  = data.getData();
        int length = data.getLength();
        //输出数据
        System.out.println("send--->>"+address.getHostAddress());
        System.out.println(new String(receivedata,0,length));
        System.out.println(new String(bytes,0,length));
        //释放资源
        socket.close();

说明:在接收端运行的时候,程序会在

socket.receive(data);

这一步进行阻塞,也就是等待发送端发送数据。接收的时候,也是用DatagramPacket类进行接收。

获取数据的方式有两种,一个是构造方法中传入的bytes参数,接受到数据后会直接写到bytes里;还有一种接受方式是通过DatagramPacket实例化对象的getData()方法,赋值给任意要给byte数组。

当然,在Socket编程中有一些墨守成规的规定,也是需要遵守的。

注意事项:

  1. 如果发送端发送的端口号是错误的,因为UDP是一种不需要建立连接的协议,所以这个数据是可以正常发出去的,也不会出现异常。但是接收方无法接收到数据
  2. 端口号的作用和属性前面也描述了,所以一个端口一次只能给一个进程使用,如果已经被使用的端口,其他程序想要去使用就会抛出端口被占用的异常。

 

2.TCP协议

  • 发送端执行步骤
  1. 创建发送端Socket对象(创建连接)
  2. 获取输出流对象
  3. 发送数据
  4. 释放资源

具体代码如下:

 

    public static void main(String[] args) throws IOException {
        //创建发送端Socket对象(创建连接)
        Socket socket = new Socket(InetAddress.getByName("DESKTOP-KHNDCKQ"),8899);
        //获取输出流对象
        OutputStream out =   socket.getOutputStream();
        //发送数据
        String str = "hello,TCP,I'm sender";
        out.write(str.getBytes());
        //释放资源
        //out.close();
        socket.close();
    }

 

在TCP协议中,客户端(发送端)使用的是Socket对象。而流就相当于管道一样,TCP协议的所有数据都是从管道里传输的。这里需要注意的是,Socket对象除了能获取输出流对象,也能获取输入流对象,这样发送端并不一定只能发送。也是能够获取到数据的。

 

  • 接收端执行步骤
  1. 创建接收端Socket对象
  2. 监听(阻塞)
  3. 获取输入流对象
  4. 获取数据
  5. 输出数据
  6. 释放资源

具体代码如下:

       //创建接收端Socket对象
        ServerSocket serverSocket = new ServerSocket(8899);
        //监听(阻塞)
        Socket socket = serverSocket.accept();
        //获取输入流对象
        InputStream inputStream = socket.getInputStream();
        //获取数据
        byte[] bytes = new byte[1024];
        int length = inputStream.read(bytes);//用于存储读取到的字节个数
        //输出数据
        InetAddress inetAddress = socket.getInetAddress();
        System.out.println("sender-->"+inetAddress.getHostAddress());
        System.out.println(new String(bytes,0,length));
        //释放资源
        socket.close();
        //serverSocket.close();
    }

接收端我们用的是ServerSocket类而不是Socket,这一点需要注意

最后一行把服务端关闭方法给注释了,这是因为现实生产场景中,并不是通信一次就直接结束。所以我们的服务端一般情况下可以不用关闭,用于下一次的接收。

第二步我们需要创建监听,就是用服务端的ServerSocket去创建Socket对象,因为只有在这个对象中我们才可以去调用创建输入、输出流的方法,从而进一步去拿到传输的数据。

 

posted @ 2018-10-01 23:06  建宁小骄傲  阅读(108)  评论(0编辑  收藏  举报