网络编程---终极版

概述

  • 网络编程中有两个主要的问题:

    • 如何准确地位网络上一台或多台主机;定位主机上的特定应用
    • 找到主机后如何可靠高效地进行数据传输

网络通信要素

  • 网络编程中的两个要素

    • 对应问题一:IP和端口号
    • 对应问题二:提供网络通信协议:TCP/IP参考模型(应用层(应用层+表示层+会话层)、传输层、网络层、数据链路层(物理层+数据链路层))

IP

  • 唯一定位一台网络上计算机
  • 在Java中使用InetAddress类代表IP
  • 本机地址:127.0.0.1 <=> localhost
  • InetAddress类没有提供公共的构造器,而是提供了如下几个静态方法来获取 InetAddress实例
    • getByName(String host)
    • getLocalHost()
  • 常用方法
    • getHostName() //域名
    • getHostAddress() //ip
    • public boolean isReachable(int timeout) //测试是否可以达到该地址

端口

  • 标识正在计算机上运行的进程(程序)

  • 不同进程有不同的端口号,用来区分软件

  • 规定为一个16位的整数 0~65535

  • 单个协议下,端口号不能冲突

  • 端口分类

    • 公有端口 0~1023

      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口:1024~49151,分配用户或程序

      • Tomcat:8080
      • MySQL:3306
      • Oracle:1521
    • 动态、私有:49152~65535

      netstat -ano #查看所有的端口
      netstat -ano|findstr "5900" #查看指定端口
      tasklist|findstr "8696" #查看指定端口的进程
      
  • 端口号与IP地址的组合得出一个网络套接字:Socket

通信协议

协议:约定,就好比我们现在说的普通话。

网络通信协议:速率,传输码率,代码结构,传输控制……

TCP/IP协议簇:实际上是一组协议

重要:

  • TCP:用户传输协议
  • UDP:用户数据报协议

出名的协议:

  • TCP:
  • IP:网络互连协议

TCP UDP 对比

  • TCP协议编程:打电话

    • 连接,可靠的数据传输(三次握手 四次挥手);进行大数据量传输;传输完成,释放连接,效率低
  • UDP协议编程:发短信

    • 不连接,不可靠;以数据报形式发送,数据报限定64k;不管有没有准备好,都可以发给你,效率高
    • 导弹

TCP

  • 客户端发送信息给服务器,服务器将数据显示在控制台

    客户端:

    1. 连接服务器Socket
    2. 发送消息
    Socket socket = null;
            OutputStream os = null;
            try {
                //1.创建Socket对象,指明服务器端的ip和端口号
                InetAddress inet = InetAddress.getByName("127.0.0.1");
                int port = 8899;
                //2.创建一个socket连接
                socket = new Socket(inet,port);
                //3.获取一个输出流,用于输出数据 发送消息
                os = socket.getOutputStream();
                
     //           fis = new FileInputStream(new File("day02\\hello.txt"));
    //            byte[] c = new byte[1024];
    //            int len;
    //            while ((len =fis.read(c)) != -1){
    //                os.write(c,0,len);
    //            }
                //写出数据的操作
                os.write("你好,我是客户端mm".getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (os != null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    

    服务器端:

    1. 建立服务器的端口ServerSocket
    2. 等待用户的链接accept
    3. 接受用户的消息
    ServerSocket ss = null;
            Socket socket = null;
            InputStream is = null;
            ByteArrayOutputStream baos = null;
            try {
                //1.创建服务器端的SeverSocket,指明自己的端口号
                ss = new ServerSocket(8899);
                //2.调用accept()表示接受来自于客户端的信息
                socket = ss.accept();
                //3.获取输入流 读取客户端的消息
                is = socket.getInputStream();
    			
    // 			  new FileOutputStream(new File("day02\\1.txt"));
    //            byte[] b = new byte[1024];
    //            int len;
    //            while ((len = is.read(b)) != -1){
    //                fos.write(b,0,len);
    //            }
                //管道流
                baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) != -1){
                    baos.write(buffer,0,len);
                }
                System.out.println(baos.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //关闭资源
                baos.close();
                is.close();
                socket.close();
                ss.close();
            }
        }
    
文件上传

客户端

package com.sdyu.socket;

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

/**
 * 客户端:发送文件给服务器端
 * @author ht
 * @date 2021/2/20
 **/
public class Client01 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 9090);
        OutputStream os = socket.getOutputStream();
        FileInputStream fis = new FileInputStream(new File("day01\\1.txt"));
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

        //通知服务器,我已经结束了
        socket.shutdownOutput();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream is = socket.getInputStream();
        byte[] buffer2 = new byte[2014];
        int len2 = 0;
        while ((len2 = is.read(buffer2)) !=-1 ) {
              baos.write(buffer2,0,len2);
        }
        System.out.println(baos.toString());

        is.close();
        baos.close();
        fis.close();
        os.close();
        socket.close();
    }
}

服务器端

package com.sdyu.socket;

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

/**
 * 服务器端:将文件保存在本地,并返回”发送成功“给客户端
 * @author ht
 * @date 2021/2/20
 **/
public class Server01 {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(9090);
        Socket accept = ss.accept();
        InputStream is = accept.getInputStream();
        FileOutputStream pos = new FileOutputStream(new File("3.txt"));
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer)) != -1) {
            pos.write(buffer,0,len);
        }

        OutputStream os = accept.getOutputStream();
        os.write("发送成功!".getBytes());

        os.close();
        pos.close();
        is.close();
        accept.close();
        ss.close();
    }
}
Tomcat

客户端:

  • 自定义 C
  • 浏览器 B

服务器端:

  • 自定义 S
  • Tomcat服务器 S java后台开发

UDP

发短信:不用连接,需要知道对方的地址!

发送消息

发送端

package com.sdyu.socket;

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

/**
 * @author ht
 * @date 2021/2/20
 **/
public class UdpClientTest01 {
    public static void main(String[] args) throws Exception {
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();

        //2.建包
        String msg = "你好啊,服务器!";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,9090);

        //3.发送包
        socket.send(packet);

        //4.关闭流
        socket.close();
    }
}

接收端

package com.sdyu.socket;

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


/**
 * @author ht
 * @date 2021/2/20
 **/
public class UdpServerTest01 {
    public static void main(String[] args) throws Exception {
        //开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);

        socket.receive(packet); //阻塞接收

        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));

        //关闭连接
        socket.close();
    }
}

循环发送消息

package com.sdyu.socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
 * @author ht
 * @date 2021/2/20
 **/
public class UdpSentDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8000);

        //准备数据:控制台读取 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 (data.equals("bye")) {
                break;
            }
        }
        socket.close();
    }
}

循环接收消息

package com.sdyu.socket;

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

/**
 * @author ht
 * @date 2021/2/20
 **/
public class UdpReceiveDemo01 {
    public static void main(String[] args) throws Exception {
        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, data.length);
            System.out.println(receiveData);
            if (receiveData.equals("byte")) {
                break;
            }
        }
        socket.close();
    }
}

URL

  • <传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表

  • URL编程

    //1.下载地址
    URL url = new URL("http://192.168.14.1000:8080/examples/hello.txt?username=Tom ");
    
    //2.连接到这个资源 HTTP
    HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
    
    InputStream is = urlConnection.getInputStream();
    
    FileOutputStream fileOutputStream = new FileOutputStream("2.txt");
    
    byte[] buffer = new byte[1024];
    int len = 0;
    while ((len = is.read(buffer)) != -1) {
        fileOutputStream.write(buffer,0,len);
    }
    
    fileOutputStream.close();
    is.close();
    urlConnection.disconnect();//断开连接
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值