Java中的网络支持Socket应用

title: Java中的网络支持Socket应用
date: 2019-05-04 14:00:00

Java中的网络支持Socket应用

前言:

单机的程序终究会被淘汰的,所以还是要让你的程序软件赋予联网通信的能力,恰恰Java提供了Socket这种功能强大的类,方便Java程序员进行网络应用开发。

准备工作:

首先你得先学一下网络的基础知识,IP地址,端口,网络协议

IP地址:

为了实现网络中不同计算机之间的通信,每台机器都必须有一个唯一的标识---IP地址。IP地址格式:数字型。如192.168.0.1,想深入学习可以看看《探索Linux的网络世界》

端口:

用于区分不同应用程序;端口号范围为0~65535,其中0~1023为系统所保留,常见端口:http:80 ;ftp:21; telnet: 23

网络协议:

 

IP地址和端口号组成所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础

理解完上述的网络知识的基础,我们来学一下Java中的网络支持,针对网络通信的不同层次Java提供的网络功能有四大类:

Java提供的网络功能有四大类:

InetAddress:

用于标识网络上的硬件资源,通俗来说,用来标识IP地址的

URL:

统一资源定位符,通过URL可以直接读取或写入网络上的数据

Socket:

使用TCP协议实现网络通信的Socket相关的类

Datagram:

使用UDP协议,将数据保存在数据报中,通过网络进行通信

简单的说了一下Java提供的网络功能有四大类的通俗解析,下面我们看一下他们的用,话不多说,我贴上代码,代码实现简单,编程开发中遇到建议查看Java文档中具体介绍

InetAddress:

public class demo1{
/*
*java中InetAddress的应用
*/
public static void main(String[]args)throws Unknow HostException{
    //获取本机的InetAddress实例
    InetAddress address=InetAddress.getLocalHost();
    System.out.println("计算机名"+address.getHostName());
    System.out.println("IP地址"+address.getHostAddress());
    //获取字节数组形式的IP地址
    byte [] bytes=address.getaddress();
    System.out.println("字节数组形式的IP"+Arrays.toString(bytes));
  //直接输出InetAddress对象
    System.out.println(address);
    //根据机器名获取InetAddress实例
    InetAddresss address2=InetAddress.getByName("hkq");
 System.out.println("计算机名"+address2.getHostName());
    System.out.println("IP地址"+address2.getHostAddress()); 
    //根据IP获取InetAddress实例
     InetAddresss address2=InetAddress.getByName("1.1.1.10");
 System.out.println("计算机名"+address2.getHostName());
 System.out.println("IP地址"+address2.getHostAddress());
    
}
}
​

java中URL的应用

public class demo2{
/*
*java中URL的应用
*URL由两部分组成:协议名称和资源名称,中间用冒号隔开
*在1java.net包中提供了URL类来表示URL
*/
public static void main(String[]args)throws Unknow HostException{
    try{
    //创建一个URL实例
    URL baidu=new URL("http://www.baidu.com");
    //?后面表示参数,#后面表示锚点
    URL url=new URL(baidu,"/index.html?username=hkq#test");
    System.out.println("协议: "+url.getProtocol());  
    System.out.println("主机: "+url.getHost());
    //如果未指定端口号,则使用默认的端口号,此时getPort()方法返回值为-1    
    System.out.println("端口:"+ url.getPort());
    System.out.println("文件路径"+url.getPath());
    System.out.println("文件名"+url.getFile());
    System.out.println("相对路径"+url.getRef());
    System.out.println("查询字符串"+url.getQuery()); 
   /*
   *使用URL读取网页内容
   *通过URL对象的openStream()方法可以得到指定资源的输入流
   *通过输入流可以读取、访问网络上的数据
   */
   //创建一个URL实例
   URL url=new URL("http:hongkaiqing.cn");
   //通过URL的openStream方法获取URL对象所表示的资源的字节输入流
   InputStream is =url.openStream();
   //将字节输入流转换为字符
   InputStreamReader isr=new InputStreamReader(is,"utf-8");      //为字符输入流添加缓冲,添加读取的效率
   BufferedReader br=new BufferedReader(isr);
   //定义string类型的data接收读取数据
   String datta =br.readLine();
   //循环读取数据     
   while(data!=null){
       //输出数据
       System.out.println(data);
       //再读取下一行数据
       data=br.readLine();
   }
      //关闭资源
      br.close();
      isr.close();
      is.close();  
    }cath (MalformedURLException e){
        e.printStackTrace();
    }cath (MalformedURLException e){
        e.printStackTrace();
    } 
}
}

Socket

刚才有说,Socket是使用TCP协议实现网络通信的Socket相关的类,那啥是TCP呢?欢迎你百度一下,其实TCP协议是面向连接、可靠的、有序的......Socket通信是以字节流方式发送数据基于TCP协议实现网络通信的类,客户端的Socket类;服务器端的ServerSocket类,具体流程嘛?我们上图介绍一下:

 

what?看到这种流程,感觉是蒙圈的,通俗来说,其实这个类是用于客户端和服务器端通信的,我想想怎么理解这个呢!!!客户端和服务器端是什么意思啊?我也是接触了才想明白这个知识点,客户端通俗来说就是你电脑浏览的网页页面,用到的软件,例如:微信、QQ...

服务器端通俗来说就是一台远程的电脑,一台不会关机的电脑,它提供了两个IP供你访问,一个公网IP,一个内网IP(这个暂时不用管),公网IP是你登录这台远程电脑的唯一标识...其他你不懂就百度吧,我不想打字了

我怎么扯远了,哎,我们谈回这个Socket类,我们用一个登录的小案例,尝试理解这个Socket类

实现登录小案例:通俗来说就是客户端发送账号密码等用户信息给服务器端,服务器端根据客户端请求进行响应,

服务器端实现步骤;

1.创建ServerSocket对象,绑定监听端口

2.通过accept()方法监听客户端请求

3.连接建立后,通过输入流读取客户端发送的请求信息

4.通过输出流向客户端发送响应信息

5.关闭相关资源

客户端实现步骤;

1.创建Socket对象,指明需要连接的服务器的地址和端口号

2.连接建立后,通过输出流读取服务器端发送请求信息

3.通过输入流获取服务器端响应信息

4.关闭相关资源

大概实现的步骤就这些了....,下面贴上我实现的简陋代码,servert类代表实现服务器端代码,client类代表客户端实现代码...

package SinginScoket;
​
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
​
/***
 * 基于TCP协议的Socket,实现用户登录
 * 服务器端
 * @author hkq
 *
 */
public class Servert {
    public static void main(String[] args) {
    try {
        //1.创建一个服务器端的Socket,即ServerSocket,指定绑定的端口,并监听此端口
        ServerSocket serverSocket=new ServerSocket(8088);
        //2.调用accept()方法开始监听,等待客户端的连接
        System.out.println("服务器端启动,等待客户端连接");
        Socket socket= serverSocket.accept();
        //3.获取字节输入流,并读取客户端信息
        InputStream is=socket.getInputStream();
        //4.将字节流装换为字符流,好处是提高读取的效率
        InputStreamReader isr=new InputStreamReader(is);
        //5.搭配使用,为字符输入流添加缓冲
        BufferedReader br=new BufferedReader(isr);
        //6.定义String类型的info,循环读取客户端信息并在控制台输出
        String info=null;
        while ((info=br.readLine())!=null) {
            System.out.println("服务器端接收到客户端数据为:"+info);  
        }
        //7.关闭socket输入流
        socket.shutdownInput();
        //8.获取输出流,响应客户端的请求
        OutputStream os =socket.getOutputStream();
        //将字节输出流转换为打印输出流
        PrintWriter pw=new PrintWriter(os);
        //服务器端向客户端发送响应信息
        pw.write("登录成功,欢迎你");
        //调用flush()方法刷新缓存
        pw.flush();
        //9.关闭资源
        pw.close();
        os.close();
        br.close();
        isr.close();
        is.close();
        socket.close();
        serverSocket.close();
        } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
​
    }
​
}
​

客户端:

package SinginScoket;
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
​
/***
 * 客户端
 * @author hkq
 *
 */
public class Client {
​
    public static void main(String[] args) {
        try {
            //1.创建客户端Socket,指定`服务器地址和端口
            Socket socket=new Socket("127.0.0.1", 8088);
            //2.连接建立后,通过获取字节输出流读取服务器发送信息
            OutputStream os =socket.getOutputStream();
            //将字节输出流转换为打印输出流
            PrintWriter pw=new PrintWriter(os);
            //向服务器端发送用户信息请求
            pw.write("用户名: admin;密码: 123");
            //刷新缓存
            pw.flush();
            //关闭scoket的输出流
            socket.shutdownOutput();
            //获取输入流,并读取服务器端的响应信息
            InputStream is=socket.getInputStream();
            //将字节流装换为字符流,好处是提高读取的效率
            InputStreamReader isr=new InputStreamReader(is);
            //搭配使用,为字符输入流添加缓冲
            BufferedReader br=new BufferedReader(isr);
            //定义String类型的info,循环读取服务器信息响应并在控制台输出
            String info=null;
            while ((info=br.readLine())!=null) {
                System.out.println("客户端接收到服务器端数据为:"+info);  
            }
        
            //关闭所有资源
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
            } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
​
    }
​
}
​

运行的时候,一定是服务器端的代码先运行,因为客户端的代码先运行会因为找不到服务器端的出现错误提示.....

Datagram:

使用UDP协议,将数据保存在数据报中,通过网络进行通信。什么是UDP协议?百度给的解析:UDP协议(用户数据报协议)是无连接、不可靠、无序的,以数据报作为数据传输的载体进行数据传输时,首先需要将要传输的数据定义成数据报,在数据报中指明数据所达到的Socket(主机地址和端口号),然后再将数据报发出去...什么鬼啊?我通俗不了啊,算了,我们还是先看这个Datagram类的用法吧,它提供了两个相关操作类:

DatagramPacket: 表示数据报包

DatagramSocket:进行端到端通信的类

我们还是用一个登录案例了解一下这个Datagram类所使用的UDP编程

服务器端实现步骤:

1.创建DatagramSocket,指定端口号

2.创建DatagramPacket

3.接收客户端发送的数据信息

4.读取数据

package UDPsingin;
​
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
​
/***
 * 服务器端,实现UDP的用户登录
 * @author hkq
 *
 */
public class UDPserver {
​
    public static void main(String[] args) throws IOException {
        /***
         * 服务器端接收客户端发送的数据
         */
        //1.创建服务端DatagramSocket,指定端口
        DatagramSocket socket=new DatagramSocket(8082);
        //2.创建数据报,用于接收客户端发送的数据
        //创建字节数组,指定接收数据包的大小
        byte [] data=new byte[1024];
        DatagramPacket packet=new DatagramPacket(data, data.length);
        System.out.println("服务器端已启动,等待客户端连接");
        //3.接收客户端发送的数据
        //此方法在接收到数据报之前会一直阻塞
        socket.receive(packet);
        //4.读取数据
        String  info=new String(data,0,packet.getLength());
        System.out.println("这里是服务器,客户端对我说:"+info);
        /***
         * 服务器端向客户端响应数据
         */
        //1.定义客户端的地址、端口、数据
        InetAddress address=packet.getAddress();
        int port=packet.getPort();
        byte[]data2="登录成功".getBytes();
        //2.创建数据报,包含响应的数据信息
        DatagramPacket packet2=new DatagramPacket(data2, data2.length, address, port);
        //3.响应客户端,发送数据报
        socket.send(packet2);
        //4.关闭资源
        socket.close();
    }
​
}
​

客户端实现步骤:

1.定义发送信息(服务器地址,端口号)

2.创建DatagramPacke数据报t,包含将要发送的信息

3.创建DatagramSocket对象,实现数据发送

4.发送数据

package UDPsingin;
​
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
​
/***
 * 客户端,实现UDP的用户登录
 * @author hkq
 *
 */
public class UDPClient {
   /***
    * 向服务器端发送数据
    * @param args
    * @throws IOException
    */
    public static void main(String[] args) throws IOException  {
    //1.定义服务器的地址、端口号、数据
    InetAddress address=InetAddress.getByName("127.0.0.1"); 
    int port=8082;
    byte []data="用户名: admin;密码: 456".getBytes();
    //2.创建数据报,包含发送的数据信息
    DatagramPacket packet=new DatagramPacket(data, data.length, address, port);
    //3.创建DatagramSocket对象
    DatagramSocket socket=new DatagramSocket();
    //4.向服务器发送数据报
    socket.send(packet);
    /***
     * 接收服务器端响应的数据
     *
     */
    //1.创建数据报,用于接收服务器端响应的数据
    byte[] data2=new byte[1024];
    DatagramPacket packet2=new DatagramPacket(data2, data2.length);
    //2.接收服务器端响应的数据
    socket.receive(packet2);
    //3.读取数据
    String reply=new String(data2, 0, packet2.getLength());
    System.out.println("这里是客户端,服务器反馈信息:"+reply);
    //关闭资源
    socket.close();
    
​
    }
​
}
​

运行的时候,一定是服务器端的代码先运行,因为客户端的代码先运行会因为找不到服务器端的出现错误提示…..

重点掌握:

Socket通信原理,基于TCP的Socket通信

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值