网络编程详解

网络编程详解

一. 网络通信的两个要素

  1. 网络编程中有两个主要的问题:
    如何准确的定位到网络上的一台或者多台主机
    找到主机之后如何进行通信
  2. 网络编程中的要素:
    IP和端口号 (关于ip的类)
    网络通信协议 (关于TCP UDP的类 )

二. IP地址

用来唯一定位一台网络上的计算机
IP 地址的分类

  1. 分为IPv4和IPv6
    IPv4 四字节 32位 组成 0~255
    IPv6 十六字节 128位 组成

  2. 分为公网(互联网)和私网(局域网)
    公网地址的范围:

    A类:地址范围1.0.0.0~127.255.255.255,主要分配给主机数量多、局域网数量少的大型网络;

    B类:地址范围为128.0.0.0至191.255.255.255,一般为国际大公司及政府机构使用;

    C类:地址范围为192.0.0.0至223.255.255.255,为一般小型公司校园网研究机构;

    D类:地址范围由224.0.0.0至239.255.255.255。

    E类:地址范围为240.0.0.0至255.255.255.255,暂时预留。

    私网地址的范围:

    A类地址:10.0.0.0~10.255.255.255

    B类地址:172.16.0.0~172.31.255.255

    C类地址:192.168.0.0~192.168.255.255

JAVA代码实现:

//测试ip
import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //查询本地地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            InetAddress inetAddress2 = InetAddress.getByName("localhost");
            InetAddress inetAddress3 = InetAddress.getLocalHost();
            System.out.println(inetAddress1);
            System.out.println(inetAddress2);
            System.out.println(inetAddress3);
            //查询网站Ip地址
            InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress4);
            //常用方法
            System.out.println(inetAddress4.getAddress());
            System.out.println(inetAddress4.getCanonicalHostName());
            System.out.println(inetAddress4.getHostAddress());
            System.out.println(inetAddress4.getHostName());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}
---------------结果---------------
/127.0.0.1
localhost/127.0.0.1
莫诺蒙/172.28.177.130
www.baidu.com/110.242.68.4
[B@135fbaa4
110.242.68.4
110.242.68.4
www.baidu.com

三. 端口

端口表示计算机上的一个程序的进程
不同的进程有不同的端口号!用来区分软件!
规定范围为:0~65535

常用端口号:

公有端口:0~1023
HTTP:80
HTTPS:443
FTP:21
TELNET:23
程序注册端口:1024~49151
Tomcat:8080
MySQL:3306
Oracle:1521
动态,私有:49152~65535

netstat-ano #查看所有的端口
netstat-ano | findstr “xxx” #查看指定的端口
tasklist | findstr “xxx” #查看指定端口的进程

import java.net.InetSocketAddress;

public class TestInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1",8080);
        InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost",8080);
        System.out.println(inetSocketAddress1);
        System.out.println(inetSocketAddress2);

        System.out.println(inetSocketAddress1.getAddress());
        System.out.println(inetSocketAddress1.getHostName());//地址
        System.out.println(inetSocketAddress1.getPort());//端口
    }
}

四. 通信协议

协议:一种约定
网络通信协议:速率,传输码率,代码结构,传输控制。。。
TCP/IP协议簇

  • TCP:传输控制协议
    连接,稳定
    三次握手,四次挥手
    客户端、服务器
    传输完成,释放连接,效率低
    三次握手
    四次挥手

  • UDP:用户数据报协议
    不连接,不稳定
    客户端,服务器没有明确的界限
    不管有没有准备好,都可以发给你
    DDOS攻击:洪水攻击(饱和攻击)

五. TCP

1. TCP实例

客户端:

  • 连接服务端Socket
  • 发送消息
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

//客户端
public class TcpClient {
    public static void main(String[] args) throws UnknownHostException {
        //1.要知道服务器的地址,端口号
        InetAddress serverIP = InetAddress.getByName("127.0.0.1");
        int port=9000;
        try(//2. 创建一个socket连接
                Socket socket = new Socket(serverIP,port);
                OutputStream os = socket.getOutputStream();
                ) {
            os.write("发送的消息".getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务器:

  • 建立服务的端口
  • 等待用户的连接accept
  • 接受用户消息
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务端
public class TcpSever {
    public static void main(String[] args) {
        while (true){
            try(
                    //1. 我得有一个地址
                    ServerSocket serverSocket = new ServerSocket(9000);
                    //2. 等待客户端连接过来
                    Socket socket = serverSocket.accept();
                    //读取客户端的消息
                    InputStream is = socket.getInputStream();
                    //管道流
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ) {
 /*
            老方法,在读取中文时可能会乱码
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer))!=-1){
                String msg = new String(buffer, 0, len);
                System.out.println(msg);
            }
*/
                byte[] buffer = new byte[1024];
                int len;
                while ((len=is.read(buffer))!=-1){
                    baos.write(buffer,0,len);
                }
                System.out.println(baos.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
---------------结果---------------
发送的消息
发送的消息
发送的消息

2. 文件上传

客户端

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClient {
    public static void main(String[] args){
        try(
                //1. 建立socket连接
                Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
                //2. 创建一个输入流
                OutputStream os = socket.getOutputStream();
                //3. 文件流
                FileInputStream fis = new FileInputStream("42.png");

                //确定服务器接收完毕,才能断开连接
                InputStream is = socket.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream()
                ) {
            //4. 写出文件
            byte[] buffer = new byte[1024];
            int len;
            while ((len=fis.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            socket.shutdownOutput();//通知服务器,我已经传输完了

            //接收从服务器发来的数据并输出
            byte[] buffer2 = new byte[1024];
            int len2;
            while ((len2=is.read(buffer2))!=-1){
                baos.write(buffer2,0,len2);
            }
            System.out.println(baos.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
---------------结果---------------
接收完毕

服务器

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServer {
    public static void main(String[] args) {
        try(
                //1. 创建一个服务
                ServerSocket serverSocket = new ServerSocket(9000);
                //2. 监听用户端输入
                Socket socket = serverSocket.accept();//阻塞式监听,等待用户连接
                //3. 获取输入流
                InputStream is = socket.getInputStream();
                //文件输出
                FileOutputStream fos = new FileOutputStream("receive.png")) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }

            //通知客户端接收完毕
            OutputStream os = socket.getOutputStream();
            os.write("接收完毕".getBytes());

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

六. Tomcat

服务器

  • 自定义 S
  • Tomcat服务器 S JAVA后台开发,用别人的服务器

客户端

  • 自定义 C
  • 浏览器 B

七. UDP

1. 消息发送实例:

发送端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//不需要连接服务器
public class UdpClient {
    public static void main(String[] args) {
        try(//1. 建立一个socket包
                DatagramSocket socket = new DatagramSocket()) {
            //2. 建立包
            String msg="服务器你好,我是客户端";
            //发送给谁
            InetAddress localhost = InetAddress.getByName("localhost");
            int port= 9090;
            //msg.getBytes()  数据,
            //0,msg.getBytes().length  数据起始
            //localhost,port  发送给谁
            DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
            socket.send(packet);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

接收端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
//等待客户端连接
public class UdpServer {
    public static void main(String[] args){

        try(//开放端口
            DatagramSocket socket = new DatagramSocket(9090)) {
            //接受数据包
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);//接收
            socket.receive(packet);//阻塞接收
            System.out.println(new String(packet.getData(),0,packet.getData().length));
            System.out.println(packet.getAddress().getHostAddress());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
---------------结果---------------
服务器你好,我是客户端                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
127.0.0.1

2. UDP聊天实现

实例一:

  • 循环发送
//发送端
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UdpSender {
    public static void main(String[] args) {
        try(
                DatagramSocket socket = new DatagramSocket(9000);
                //准备数据:控制台读取System.in
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        ) {

            while (true){
                String data = reader.readLine();
                byte[] datas = data.getBytes();
                //发送端
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
                socket.send(packet);
                if ("bye".equals(data)){
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
---------------发送了---------------
nihao
客户端
结束
bye
//接收端
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpReceive {
    public static void main(String[] args) {

        try(
                DatagramSocket socket = new DatagramSocket(6666)
        ) {
            while (true){
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet);//阻塞式接收包裹
                //断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, packet.getLength());
                System.out.println(receiveData);
                if ("bye".equals(receiveData)){
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
---------------接收到---------------
nihao
客户端
结束
bye

实例二:

多线程接收发送实现

//多线程发送端
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader reader = null;

    private int formPort;
    private String toIp;
    private int toPort;

    public TalkSend(int formPort, String toIp, int toPort) {
        this.formPort = formPort;
        this.toIp = toIp;
        this.toPort = toPort;
        try {
            socket = new DatagramSocket(formPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            try {
                String data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIp,this.toPort));
                socket.send(packet);
                if("bye".equals(data)){
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

//多线程接收端
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TalkReceive implements Runnable{
    DatagramSocket socket = null;
    private int port;

    public TalkReceive(int port) {
        this.port = port;

        try {
            socket = new DatagramSocket(port);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void run() {
        while (true){
            try {
                //准备接受数据
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, 0, container.length);
                socket.receive(packet);//阻断式接受

                //断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, packet.getLength());
                System.out.println(packet.getPort()+" : "+receiveData);
                if ("bye".equals(receiveData)){
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}
//用户1
public class Talk01 {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(7777,"localhost",8888)).start();
        new Thread(new TalkReceive(9999)).start();
    }
}
---------------结果---------------
你好
5555 : 你好
我是端口5555
5555 : 我是端口7777
再见
5555 : bye
bye
//用户2
public class Talk02 {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(5555,"localhost",9999)).start();
        new Thread(new TalkReceive(8888)).start();
    }
}
---------------结果---------------
7777 : 你好
你好
7777 : 我是端口5555
我是端口7777
7777 : 再见
bye
7777 : bye

3. URL下载

下载URL资源

//参数
import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo01 {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=monuomeng&password=123");
        System.out.println(url.getProtocol());//协议
        System.out.println(url.getHost());//IP
        System.out.println(url.getPort());//端口
        System.out.println(url.getPath());//文件
        System.out.println(url.getFile());//文件全路径
        System.out.println(url.getQuery());//参数
    }
}
//实现
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class URLDown {
    public static void main(String[] args) throws Exception {
        //下载地址
        URL url = new URL("http://localhost:8080/monuomeng/SecurityFile.txt");
        //连接到资源
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("SecurityFile.txt");
        byte[] buffer = new byte[1024];
        int len;
        while ((len=inputStream.read(buffer))!=-1){
            fos.write(buffer,0,len);//写出数据
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect();//断开连接
    }
}
---------------以本机tomcat文件实例---------------
下载结果如下图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值