您的位置:首页 > 理论基础 > 计算机网络

网络编程—TCP、UDP、IP、端口、通信协议

2020-01-15 11:31 1836 查看

网络编程

1.1、概述

计算机网络:

计算机网络是指将地理位置不同的具有独立功能的多台[计算机]及其外部设备,通过通信线路连接起来,在[网络操作系统][网络管理软件]及网络通信协议的管理和协调下,实现[资源共享]和信息传递的计算机系统。

网络编程的目的:

无线电台…传播交流信息,数据交换。通信
想要达到这个效果需要什么:

  1. 如何准确的定位网络上的一台主机 192.168.16.124:端口, 定位到这个计算机上的某个资源
  2. 找到了这个主机,如何传输数据呢?

javaweb: 网页编程 B/S

网络编程:TCP/IP C/S

1.2、网络通信的要素

如何实现网络的通信?

通信双方地址:

  • ip
  • 端口号
  • 192.168.16,124:5900

规则:网络通信的协议

TCP/IP参考模型:

小结:

  1. 网络编程中有两个主要的问题
      如何准确的定位到网络上的一台或者多台主机
    • 找到主机之后如何进行通信
  2. 网络编程中的要素
      IP 和 端口号 IP.
    • 网络通信协议 udp,tcp
  3. 万物皆对象

1.3、IP


每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了。
IP地址是用一个点来分成四段的,在计算机内部IP地址是用四个字节来表示的,一个字节代表一段,每一个字节代表的数最大只能到达255。

InetAddress类
说到IP地址,就要引入一个类:InetAddress
此类表示互联网协议 (IP) 地址。

InetAddress类无构造方法
常用方法摘要
byte[] getAddress()
返回此 InetAddress 对象的原始 IP 地址。
static InetAddress getByName(String host)
在给定主机名的情况下确定主机的 IP 地址。
String getHostAddress()
返回 IP 地址字符串(以文本表现形式)。
String getHostName()
获取此 IP 地址的主机名。
static InetAddress getLocalHost()
返回本地主机。
127.0.0.1:本机地址,主要用于测试。别名:Localhost

ip地址:InetAddress

  • 唯一定位一台网络上计算机

  • 127.0.0.1 : 本机 localhost

  • ip地址的分类

    ipv4 / ipv6

    IPV4 127.0.0.1 , 4个字节组成。, 0~255, 42亿~ ; 30亿都在北美,亚洲4亿。2011年就用尽;

  • IPV6 :128位。8个无符号整数!

    2001:0bb2:aaaa:0015:0000:0000:1aaa:1312!
  • 公网(互联网)- 私网(局域网)

      ABCD类地址
    • 192.168.xx.xx,专门给组织内部使用的
  • 域名:记忆IP问题!

      IP: www.vip.com

    代码

    package com.kuang.lesson01;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    //测试IP
    public class TestInetAddress {
    public static void main(String[] args) {
    try {
    //查询本机地址
    InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
    System.out.println(inetAddress1);
    InetAddress inetAddress3 = InetAddress.getByName("localhost");
    System.out.println(inetAddress3);
    InetAddress inetAddress4 = InetAddress.getLocalHost();
    System.out.println(inetAddress4);
    
    //查询网站ip地址
    InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
    System.out.println(inetAddress2);
    
    //常用方法
    // System.out.println(inetAddress2.getAddress());
    System.out.println(inetAddress2.getCanonicalHostName()); //规范的名字
    System.out.println(inetAddress2.getHostAddress()); //ip
    System.out.println(inetAddress2.getHostName()); //域名,或者自己电脑的名字
    
    } catch (UnknownHostException e) {
    e.printStackTrace();
    }
    }
    }

    1.4、端口

    IP地址用来标识一台计算机,但是一台计算机上可能提供多种网络应用程序,如何来区分这些不同的程序呢?这就要用到端口。
    端口是虚拟的概念,并不是说在主机上真的有若干个端口。
    通过端口,可以在一个主机上运行多个网络应用程序。端口的表示是一个16位的二进制整数,2个字节,对应十进制的0~65535。
    MySQL(3306),Oracle(1521),Tomcat(8080)等等程序都有自己的端口
    查看端口
    用命令提示符cmd查看所有端口:netstat -ano
    查看具体程序:使用任务管理器查看PID
    InetSocketAddress类
    说到端口,则要引入一个类:InetSocketAddress
    此类实现 IP 套接字地址(IP 地址 + 端口号)。
    构造方法摘要
    InetSocketAddress(InetAddress addr, int port)
    根据 IP 地址和端口号创建套接字地址。
    InetSocketAddress(int port)
    创建套接字地址,其中 IP 地址为通配符地址,端口号为指定值。
    InetSocketAddress(String hostname, int port)
    根据主机名和端口号创建套接字地址。
    常用方法摘要
    InetAddress getAddress()
    获取 InetAddress。
    String getHostName()
    获取 hostname。
    int getPort()
    获取端口号。

    端口表示计算机上的一个程序的进程;

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

    • 被规定 0~65535

    • TCP,UDP : 65535 * 2 tcp:80,udp:80吗,单个协议下,端口号不能冲突

    • 端口分类

      公有端口 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" #查看指定端口的进程
    Ctrl+ shift + ESC
  • package com.kuang.lesson01;
    
    import java.net.InetSocketAddress;
    
    public class TestInetSocketAddress {
    public static void main(String[] args) {
    
    InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
    InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);
    System.out.println(socketAddress);
    System.out.println(socketAddress2);
    
    System.out.println(socketAddress.getAddress());
    System.out.println(socketAddress.getHostName()); //地址
    System.out.println(socketAddress.getPort()); //端口
    
    }
    }
  • -

    1.5、通信协议

    网络通信协议:

    计算机网络中实现通信必须有一些约定,即通信协议;包括对速率,传输代码,代码结构,传输控制步骤,出错控制等制定的标准。

    网络通信接口:

    为了使两个节点之间能进行对话,必须在他们之间建立通信工具(即接口),使彼此之间,能进行信息交换。接口包括两部分:

    硬件装置:实现结点之间的信息传送
    软件装置:规定双方进行通信的约定协议

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

    重要:

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

    出名的协议:

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

    TCP udp 对比

    TCP : 打电话

    • 连接,稳定

    • 三次握手
      四次挥手

      最少需要三次,保证稳定连接!
      A:你瞅啥?
      B: 瞅你咋地?
      A:干一场!
      
      A:我要走了!
      B:我真的要走了吗?
      B:你真的真的要走了吗?
      A:我的真的要走了!
    • 客户端、服务端

    • 传输完成,释放连接,效率低

    UDP : 发短信

    • 不连接,不稳定
    • 客户端、服务端:没有明确的界限
    • 不管有没有准备好,都可以发给你…
    • 导弹
    • DDOS : 洪水攻击! (饱和攻击)

    1.6、TCP

    传输消息

    注意:要先启动服务器,再点击客户端,才可以传输消息。否则代码会报错!!!
    客户端

    1. 连接服务器 Socket
    2. 发送消息
    package com.kuang.lesson02;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    //客户端
    public class TcpClientDemo01 {
    public static void main(String[] args) {
    
    Socket socket = null;
    OutputStream os = null;
    
    try {
    //1. 要知道服务器的地址,端口号
    InetAddress serverIP = InetAddress.getByName("127.0.0.1");
    int port = 9999;
    //2. 创建一个socket连接
    socket = new Socket(serverIP,port);
    //3. 发送消息 IO流
    os = socket.getOutputStream();
    os.write("你好,欢迎学习Java".getBytes());
    
    } catch (Exception 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. 接收用的消息
    package com.kuang.lesson02;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    //服务端
    public class TcpServerDemo01 {
    public static void main(String[] args) {
    ServerSocket serverSocket = null;
    Socket socket = null;
    InputStream is = null;
    ByteArrayOutputStream baos = null;
    
    try {
    //1. 我得有一个地址
    serverSocket = new ServerSocket(9999);
    
    while (true){
    //2. 等待客户端连接过来
    socket = serverSocket.accept();
    //3. 读取客户端的消息
    is = socket.getInputStream();
    
    //管道流
    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());
    }
    
    /*
    byte[] buffer = new byte[1024];
    int len;
    while ((len=is.read(buffer))!=-1){
    String msg = new String(buffer, 0, len);
    System.out.println(msg);
    }
    */
    
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    //关闭资源
    if (baos!=null){
    try {
    baos.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    if (is!=null){
    try {
    is.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    if (socket!=null){
    try {
    socket.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    
    if (serverSocket!=null){
    try {
    serverSocket.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    
    }
    
    }
    }

    文件上传

    服务器端

    package com.kuang.lesson02;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TcpServerDemo02 {
    public static void main(String[] args) throws Exception {
    //1. 创建服务
    ServerSocket serverSocket = new ServerSocket(9000);
    //2. 监听客户端的连接
    Socket socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接
    //3. 获取输入流
    InputStream is = socket.getInputStream();
    
    //4. 文件输出
    FileOutputStream fos = new FileOutputStream(new File("1.jpg"));
    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());
    
    //关闭资源
    fos.close();
    is.close();
    socket.close();
    serverSocket.close();
    
    }
    }

    客户端

    package com.kuang.lesson02;
    
    import java.io.*;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
    //1.创建一个Socket连接
    Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
    //2、 创建一个输出流
    OutputStream os = socket.getOutputStream();
    
    //3. 读取文件
    FileInputStream fis = new FileInputStream(new File("qinjiang.jpg"));
    //4. 写出文件
    byte[] buffer = new byte[1024];
    int len;
    while ((len=fis.read(buffer))!=-1){
    os.write(buffer,0,len);
    }
    
    //通知服务器,我已经结束了
    socket.shutdownOutput(); //我已经传输完了!
    
    //确定服务器接收完毕,才能够断开连接
    InputStream inputStream = socket.getInputStream();
    //String byte[]
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
    byte[] buffer2 = new byte[2014];
    int len2;
    while ((len2=inputStream.read(buffer2))!=-1){
    baos.write(buffer2,0,len2);
    }
    
    System.out.println(baos.toString());
    
    //5.关闭资源
    baos.close();
    inputStream.close();
    fis.close();
    os.close();
    socket.close();
    }
    }

    Tomcat

    服务端

    • 自定义 S
    • Tomcat服务器 S : Java后台开发!

    客户端

    • 自定义 C
    • 浏览器 B

    1.7、UDP

    使用基于UDP协议的Socket网络编程实现
    不需要利用IO流实现数据的传输
    每个数据发送单元被统一封装成数据包的方式,发送方将数据包发送到网络中,数据包在网络中去寻找他的目的地,一切以包为中心。
    UDP基本概念:
    DatagramSocket:用于发送或接收数据包的套接字
    DatagramPacket:数据包

    发送消息

    package com.kuang.lesson03;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    //不需要连接服务器
    public class UdpClientDemo01 {
    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, port);
    
    //3. 发送包
    socket.send(packet);
    
    //4. 关闭流
    socket.close();
    }
    }

    接收端

    package com.kuang.lesson03;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    //还是要等待客户端的链接!
    public class UdpServerDemo01 {
    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.kuang.chat;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    
    public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception {
    
    DatagramSocket socket = new DatagramSocket(8888);
    
    //准备数据: 控制台读取 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.kuang.chat;
    
    import javax.xml.stream.FactoryConfigurationError;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    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); //阻塞式接收包裹
    
    //断开连接  bye
    byte[] data = packet.getData();
    String receiveData = new String(data, 0, data.length);
    
    System.out.println(receiveData);
    
    if (receiveData.equals("bye")){
    break;
    }
    
    }
    
    socket.close();
    
    }
    }

    1.8、URL

    URI=URL+URN

    URI:Uniform Resource Identifier ,统一资源标志符。
    URL:Uniform Resource Locator,统一资源定位符。
    URN:Uniform Resource Name,统一资源命名。
    网络三大基石:HTML,HTTP,URL
    URL
    在www上,每一信息资源都有统一且唯一的地址,即统一资源定位符。Uniform Resource Locator。
    如:https://localhost:8080/index.html ,有4部分组成。(协议,主机域名或IP,端口号,资源文件名)
    URL类
    构造方法摘要
    URL(String spec)
    根据 String 表示形式创建 URL 对象。
    URL(String protocol, String host, int port, String file)
    根据指定 protocol、host、port 号和 file 创建 URL 对象。
    URL(String protocol, String host, String file)
    根据指定的 protocol 名称、host 名称和 file 名称创建 URL。

    常用方法摘要
    String getAuthority()
    获取此 URL 的授权部分。
    int getDefaultPort()
    获取与此 URL 关联协议的默认端口号。
    String getFile()
    获取此 URL 的文件名。
    String getHost()
    获取此 URL 的主机名(如果适用)。
    String getPath()
    获取此 URL 的路径部分。
    int getPort()
    获取此 URL 的端口号。
    String getUserInfo()
    获取此 URL 的 userInfo 部分。
    统一资源定位符:定位资源的,定位互联网上的某一个资源

    DNS 域名解析 www.baidu.com xxx.x…x…x

    协议://ip地址:端口/项目名/资源

    测试代码

    package com.kuang.lesson04;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.time.Year;
    
    //http://localhost:8080/qinjiang/SecurityFile.txt
    
    public class URLDemo01 {
    public static void main(String[] args) throws MalformedURLException {
    URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=kuangshen&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()); //参数
    }
    }

    下载资源

    package com.kuang.lesson04;
    
    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 {
    //1. 下载地址
    URL url = new URL("https://m10.music.126.net/20191201174818/c09b1932384617e535421702c26ccc5c/yyaac/0708/0652/0508/0b9b6827b718aa223af92bd52aa2424f.m4a");
    
    //2. 连接到这个资源  HTTP
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    
    InputStream inputStream = urlConnection.getInputStream();
    
    FileOutputStream fos = new FileOutputStream("f.m4a");
    
    byte[] buffer = new byte[1024];
    int len;
    while ((len=inputStream.read(buffer))!=-1){
    fos.write(buffer,0,len); //写出这个数据
    }
    
    fos.close();
    inputStream.close();
    urlConnection.disconnect(); //断开连接
    }
    }

    • 点赞
    • 收藏
    • 分享
    • 文章举报
    刘憨憨的小可爱 发布了28 篇原创文章 · 获赞 2 · 访问量 634 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐