网络编程

目录

  • 网络编程
    • (1)概述
    • (2)IP和端口号
      • InetAddress
    • (3)Socket
      • Socket通信模型
      • Socket通信实例
      • ServerSocket类
      • Socket类
      • TCP的Socket通信
        • Socket服务端
        • Socket客户端
      • UDP的Socket通信
        • 服务端
        • 客户端
    • (4)网络协议
    • (5)URL编程
      • URL语法规则
      • URL类

网络编程

(1)概述

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。

实现网络中的主机通信

1.通信双方的地址:IP、端口号

2.一定的规则:网络通信协议(OSI参考模型、TCP、IP协议)

(2)IP和端口号

IP地址:对应InetAddress类,一个对象代表一个IP地址;

  • IP地址唯一标识Internet上的计算机
  • 本地回环地址为(hostAddress):127.0.0.1
  • 本地主机名(hostName):localhost

IP地址分类

IPV4:4个字节组成

IPV6:16个字节,写成8个整数,每个整数用4位十六进制数表示,数之间用冒号隔开(X:X:X:X:X:X:X:X,X=_ _ _ _)

也可以分为

公网地址:万维网使用

私有地址:局域网使用,192.168开头,范围是0.0——255.255

InetAddress

InetAddress类,一个对象代表一个IP地址;

InetAddress inetAddress=InetAddress.getByName("127.0.0.1");

getByName(String host)//InetAddress类中的静态方法,获得IP地址对象
getLocalHost()//静态方法,获取本地IP地址

//常用方法(非静态)
getHostAddress()//获取本地地址
getHostName()//获取本地域名

InetAddress常用方法

序号 方法描述
1 static InetAddress getByAddress(byte[] addr) 在给定原始 IP 地址的情况下,返回 InetAddress 对象。
2 static InetAddress getByAddress(String host, byte[] addr) 根据提供的主机名和 IP 地址创建 InetAddress。
3 static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
4 String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
5 String getHostName() 获取此 IP 地址的主机名。
6 static InetAddress getLocalHost() 返回本地主机。
7 String toString() 将此 IP 地址转换为 String。

域名

www.baidu.com

本地回路地址

127.0.0.1 对应localhost

端口号

  • 标识正在计算机上运行的进程;
  • 不同的进程对应不同的端口号;
  • 端口地址是16比特,可以有在0—65535范围内的端口号;

端口分类

1.公认端口:0——1023,系统的保留端口,程序尽可能别使用这些端口;

2.注册端口:1024——49151

3.动态/私有端口:49152——65515

特定的端口号:MySQl 3306;Tomcat 8080

(3)Socket

IP地址和端口号的组合得到一个网络套接字:Socket;

Socket(套接字)用来描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发送请求或者应答网络请求;

Socket是支持TGP/IP协议的网络通信的基本操作单元,是对网络通信过程中端点的抽象表示,包含了进行网络通信所必须的五种信息:

1.连接所使用的协议;

2.本地主机的IP地址;

3.本地远程的协议端口;

4.远地主机的IP地址;

5.远地进程的协议端口;

Socket通信模型

网络编程_第1张图片

Socket通信实例

public class ServerDemo extends Thread {//服务端
    private ServerSocket serverSocket;
    public ServerDemo(int port) throws IOException{
        serverSocket=new ServerSocket(port);
        serverSocket.setSoTimeout(10000);
    }

    @Override
    public void run() {
        while (true){
            try {
                System.out.println("等待远程连接,端口号为:"+serverSocket.getLocalPort());
                Socket server=serverSocket.accept();
                System.out.println("远程主机地址:"+server.getRemoteSocketAddress());
                DataInputStream dataInputStream=new DataInputStream(server.getInputStream());
                System.out.println(dataInputStream.readUTF());
                DataOutputStream dataOutputStream=new DataOutputStream(server.getOutputStream());
                dataOutputStream.writeUTF("连接成功"+server.getLocalSocketAddress()+"\nGood bye");
                server.close();
            }catch (SocketTimeoutException e){
                System.out.println("Socket Time Out");
                break;
            }catch (IOException e){
                e.printStackTrace();
                break;
            }
        }
    }

    public static void main(String[] args) {
        int port=Integer.parseInt(args[0]);
        try{
            Thread thread=new ServerDemo(port);
            thread.run();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
public class ClientDemo {//客户端
    public static void main(String[] args) {
        String serverName=args[0];
        int port=Integer.parseInt(args[1]);
        try{
            System.out.println("连接主机:"+serverName+",端口号:"+port);
            Socket client=new Socket(serverName,port);
            System.out.println("远程主机地址:"+client.getRemoteSocketAddress());
            OutputStream outputStream=client.getOutputStream();
            DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
            dataOutputStream.writeUTF("Hello from"+client.getRemoteSocketAddress());
            InputStream inputStream=client.getInputStream();
            DataInputStream dataInputStream=new DataInputStream(inputStream);
            System.out.println("服务器响应"+dataInputStream.readUTF());
            client.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

ServerSocket类

服务器应用程序通过使用 java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。

ServerSocket 类有四个构造方法:

序号 方法描述
1 public ServerSocket(int port) throws IOException 创建绑定到特定端口的服务器套接字。
2 public ServerSocket(int port, int backlog) throws IOException 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
3 public ServerSocket(int port, int backlog, InetAddress address) throws IOException 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
4 public ServerSocket() throws IOException 创建非绑定服务器套接字。

ServerSocket 类的常用方法:

序号 方法描述
1 public int getLocalPort() 返回此套接字在其上侦听的端口。
2 public Socket accept() throws IOException 侦听并接受到此套接字的连接。
3 public void setSoTimeout(int timeout) 通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。
4 public void bind(SocketAddress host, int backlog) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。

Socket类

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象通过 accept() 方法的返回值。

Socket 类有五个构造方法:

序号 方法描述
1 public Socket(String host, int port) throws UnknownHostException, IOException. 创建一个流套接字并将其连接到指定主机上的指定端口号。
2 public Socket(InetAddress host, int port) throws IOException 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
3 public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程主机上的指定远程端口。
4 public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程地址上的指定远程端口。
5 public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字

Socket类常用方法

序号 方法描述
1 public void connect(SocketAddress host, int timeout) throws IOException 将此套接字连接到服务器,并指定一个超时值。
2 public InetAddress getInetAddress() 返回套接字连接的地址。
3 public int getPort() 返回此套接字连接到的远程端口。
4 public int getLocalPort() 返回此套接字绑定到的本地端口。
5 public SocketAddress getRemoteSocketAddress() 返回此套接字连接的端点的地址,如果未连接则返回 null。
6 public InputStream getInputStream() throws IOException 返回此套接字的输入流。
7 public OutputStream getOutputStream() throws IOException 返回此套接字的输出流。
8 public void close() throws IOException 关闭此套接字。

TCP的Socket通信

1.创建ServerSocket和Socket;

2.打开连接到的Socket的输入/输出流;

3.按照协议对Socket进行读写操作;

4.关闭输入输出流以及Socket;

Socket服务端

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

2.调用accept()方法监听客户端的请求;

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

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

5.关闭相关资源;

public static void main(String[] args) throws IOException {
    //1.创建一个服务器端Socket,即ServerSocket,绑定指定的端口,并监听此端口;
    ServerSocket serverSocket=new ServerSocket(12345);
    InetAddress inetAddress=InetAddress.getLocalHost();
    String ip=inetAddress.getHostAddress();
    Socket socket=null;
    //2.调用accept()方法,等待客户端连接;
    System.out.println("服务端已就绪,等待客户端接入,服务端ip地址: " + ip);
    socket = serverSocket.accept();
    //3.连接后获取输入流,读取客户端信息;
    InputStream inputStream=socket.getInputStream();
    InputStreamReader inputStreamReader=new InputStreamReader(inputStream,"UTF-8");
    BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
    OutputStream outputStream=null;
    PrintWriter printWriter=null;
    String info=null;
    while((info=bufferedReader.readLine())!=null){//循环读取客户端的信息
        System.out.println("客户端发来信息"+info);
        socket.shutdownInput();
        socket.close();
    }

Socket客户端

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

2.连接建立以后,通过输出流向服务器发送请求信息;

3.通过输出流获取服务器响应的信息;

4.关闭相关资源;

Socket socket = new Socket("192.168.137.1",12345);//创建客户端Socket,指定服务器和端口
OutputStream outputStream= socket.getOutputStream();//获取输出流,向客户端发送信息
PrintWriter printWriter=new PrintWriter(outputStream);
InetAddress inetAddress = InetAddress.getLocalHost();
String ip=inetAddress.getHostAddress();//获取客户端的IP地址
printWriter.write("客户端ip地址:"+ip+"接入服务器");
printWriter.close();
printWriter.flush();
socket.shutdownOutput();//关闭输出流
socket.close();

UDP的Socket通信

UDP通信无需建立发送和接收的连接,通过类DatagramSocket和DatagramPocket实现了基于UDP协议网络通信;

UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据是否一定能够安全地送到目的地,也不能确定什么时候可以送达;

服务端

1.创建DatagramSocket,指定端口号;

2.创建DatagramPacket;

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

4.读取数据;

public class UDPServer {
    public static void main(String[] args) throws IOException {
        /*
         * 接收客户端发送的数据
         */
        //1.创建服务端DatagramSocket,指定端口
        DatagramSocket datagramSocket=new DatagramSocket(12345);
        //2.创建数据报,用于接收客户端发送的数据
        byte[] data1=new byte[1024];//创建字节数组,指定接收的数据包的大小
        DatagramPacket datagramPacket1=new DatagramPacket(data1,data1.length);
        //3.接受客户端发送的数据
        System.out.println("服务端已经启动,等待客户端发送消息");
        datagramSocket.receive(datagramPacket1);//此方法在接收到数据报之前会一直堵塞
        //4.读取数据
        String info=new String(data1,0,datagramPacket1.getLength());
        System.out.println("客户端请求是:"+info);
        
        
        /*
         *响应给客户端的数据
         */
        //1.定义客户端的地址、端口号、数据
        InetAddress inetAddress=datagramPacket1.getAddress();
        int port=datagramPacket1.getPort();
        byte[] data2=new String("Hello!").getBytes();
        //2.创建数据报,包含响应给客户端的数据信息
        DatagramPacket datagramPacket2=new DatagramPacket(data2,data2.length,inetAddress,port);
        //3.响应客户端
        datagramSocket.send(datagramPacket2);
        //4.关闭资源
        datagramSocket.close();
    }
}

客户端

1.定义发送的信息;

2.创建DatagramPacket,包含要发送的信息;

3.创建DatagramSocket;

4.发送数据;

public class UDPClient {
    public static void main(String[] args) throws IOException {
        /*
         * 向服务器端发送数据
         */
        // 1.定义服务器的地址、端口号、数据
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8800;
        byte[] data = "用户名:admin;密码:123".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);
        // 4.关闭资源
        socket.close();
    }
}

小结:UDP的Socket通信就是将数据转换为字节,然后放到DatagramPacket(数据报)中,发送的时候需要指明接收者的IP地址和端口号;而接收的时候,用一个字节数组来缓存;

发送和接受都需要DatagramSocket(端对端通信类)对象来send()或者receive();

(4)网络协议

网络协议对速率、传输代码、代码结构、传输控制参数、出错控制等制定标准;

分层思想:同层间通信、上层调用下层而不再与下一层有联系;

传输层协议

  • 传输控制协议:TCP(可靠)——3次握手
  • 用户数据报协议:UDP(不可靠)

IP协议是网络层的主要协议,支持网络间互为关联的协议;

(5)URL编程

URL:统一资源定位符,标识Internet上某一资源的地址

URL 是一个网页地址,可以由字母组成,如"www.baidu.com",或互联网协议(IP)地址:192.68.20.50:端口。

URL 只能使用ASCII 字符集来通过因特网进行发送。

URL语法规则

scheme://host.domain:port/path/filename
传输协议://主机名:端口号/(路径)/文件名(#片段名?参数列表)

片段名:锚点
参数列表格式:参数名=参数值&参数名=参数值...

URL类

定义在java.net包下;

URL常用方法

序号 方法描述
1 public String getProtocal() 获取URL的协议名
2 public String getHost() 获取URL的主机名
3 public String getPort() 获取URL的端口号
4 public String getPath() 获取URL的文件路径
5 public String getFile() 获取URL的文件名
6 public String getQuery() 获取URL的查询名

你可能感兴趣的:(网络编程)