网络编程--针对TCP/IP编程

概述

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

  2. 网络编程的目的:

    • 无线电台---传播交流信息,实现数据交互。通信

  3. 想要达到的效果:

    1. 如何准确地定位网络上的一台主机?需要IP地址和端口,还要定位到这个计算机上的某个资源,不然咋知道连的是啥。

    2. 找到了这个主机,如何传输数据呢?

      • javaweb:网页编程 B/S

      • 网络编程:TCP/IP C/S

网络通信的要素

  1. 如何实现网络的通信?

    1. 需要知道通信双方地址

      • IP

      • 端口号

      -->这就可以连接到某台计算机上的具体应用

    2. 还需要知道规则:网络通信的协议

小结:

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

    • 如何准确定位到网络上的一台或多台主机

    • 找到主机之后如何进行通信

  2. 网络编程的要素

    • IP和端口号 ---学习关于IP的类

    • 网络通信协议 --学习关于UDP、TCP的类

  3. 万物皆对象

IP地址

  1. IP地址:InetAddress

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

    • 127.0.0.1:本机 localhost

    • IP地址的分类(通过以下两种方式)

      • IP地址分类:IPV4/IPV6

        • IPV4即类似127.0.0.1,由4个字节组成,每个字节的长度0~2 55。大概有42亿个,30亿都在北美,亚洲只有4亿。2011年就用尽了。

        • IPV6即类似2001:0bb2:aaaa:0015:0000:0000:1aaa:1312,128位,8个无符号整数表示。

      • 公网(互联网)-私网(局域网)

        • ABCD类地址

        • 192.168.xx.xx,专门给组织内部使用的

    • 域名:解决记忆IP问题!

        //测试IP
    public class TestTnetAddress{
       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(UnkonwnHostException e){
               e.printStackTrace();
          }
      }
    }

端口Port

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

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

    • 被规定0~65535

    • 分为TCP端口和UDP端口:正常端口数量为65535*2;TCP用了端口80,UDP也能用端口80。即单个协议下,端口号不能冲突。

    • 端口分类

      • 公有端口:0~1023,一般不要去使用,因为是分给内置的进程或服务器去使用

        • HTTP:80

        • HTTPS:443

        • FTP:21

        • Telent:23

      • 程序注册端口:1014~49151,分配给用户或程序

        • Tomcat:8080

        • MySQL:3306

        • Oracle:1521

      • 动态端口(私有端口):49152~65535

        netstat -ano #查看所有的端口
        netstat -ano|findstr "5900" #查看指定端口
        tasklist|findstr "8696" #查看指定端口的进程
    public class TestInetSocketAddress{
       public static void main(String[] args){
           InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
           System.out.println(socketAddress);
           InetSocketAddress socketAddress2 = new InetSocketAddress("localhost",8080);
           System.out.println(socketAddress2);
           
           System.out.println(socketAddress.getAddress());
           System.out.println(socketAddress.getHostName()); //地址
           System.out.println(socketAddress.getPort()); //端口
      }
    }

www.sso.com是啥?

如果不配置,则打印结果为:

通信协议

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

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

  3. 问题:非常的复杂?

  4. 大事化小:分层!

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

    • 重要:

      • TCP:用户传输协议

      • UDP:用户数据报协议

    • 出名的协议

      • TCP

      • IP:网络互连协议

    1. TCP与UDP对比

    • TCP:打电话

      • 连接,稳定

      • 三次握手,四次挥手

        最少需要三次,才能保证稳定连接
        A:你瞅啥?
        B:瞅你咋地?
        A:干一场!


        四次挥手
        A:我要走了
        B:你真的要走了吗?
        B:你真的真的要走了吗?
        A:我真的要走了

         

      • 客户端、服务端去连

      • 传输完成,释放连接

    • UDP:发短信

      • 不连接,不稳定

      • 客户端、服务端没有明确的界限

      • 不管有没有准备好,都可以发给你

      • 导弹

      • DDOS:洪水攻击!(饱和攻击)

TCP实现聊天

  1. 客户端

    1. 通过Socket连接服务器

    2. 发送消息

  2. 服务器

    1. 建立服务端口 ServerSocket

    2. 等待用户的连接 accept

    3. 接收用户的消息

//客户端
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();
              }
          }
           
      }
  }
}

//服务端
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);
           //2.等待客户端连接过来
           socket = serverSocket.accept();
           //3.读取客户端的消息
           is = socket.getInputStream();
           /*
           byte[] buffer = new byte[1024];
           int len;
           while((len=is.read(buffer))!=-1){
               String msg = new String(buffer,0,len);
               System.out.println(msg);
           }
           */
           //管道流
           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{
           //关闭资源
           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();
              }
          }
           
      }
  }
}

先启动服务端再启动客户端。

TCP文件上传实现

//客户端
public class TcpClientDemo02{
   public static void main(String[] args) throws Exception{
       //1.创建一个Socket连接
       Socket sokcet = 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=is.read(buffer))!=-1){
           baos.write(buffer,0,len);
      }
       
       //通知服务器,我已经结束了
       socket.shutdownOutput(); //我已经传输完了!
       
       //确定服务器接收完毕,才能够断开连接
       InputStream inputStream = socket.getInputStream();
       //因为来的是我不认识的东西,所以要通过管道流接收
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       byte[] buffer2 = new byte[1024];
       int len2;
       while((len2=inputStream.read(buffer))!=-1){
           baos.write(buffer,0,len);
      }
       System.out.println(baos.toString());
       
       //5.关闭资源
       baos.close();
       inputStream.close();
       fis.close();
       os.close();
       socket.close();
  }
   
   
   
   
   //服务端
public class TcpServerDemo01{
   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("receive.jpg"));
       byte[] buffer = new byte[1024];
       int len;
       while((len=is.read(buffer))!=-1){
           baos.write(buffer,0,len);
      }
       
       //通知客户端我接收完毕了
       OutputStream os = socket.getOutputStream();
       os.write("我接受完毕了,你可以断开了".getBuye());
       
       //关闭资源
       fos.close();
       is.close();
       socket.close();
       serverSocket.close();
  }
}

先启动服务端再启动客户端。

 

 

若找不到指定文件的,把想要发送的文件放到根目录下,不要放在其他文件夹里。

初识Tomcat

  1. 服务端

    • 自定义 S

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

  2. 客户端

    • 自定义 C

    • 浏览器 B

UDP消息发送

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

    发送端:

//不需要连接服务器
public class UdpClientDemo01{
   public static void main(String[] args) throws Exception{
       //1.建立一个Socket
       DatagramSocket socket = new DatagramSocket();
       
       //2.建个包
       String msd = "你好啊,服务器!";
       
       //发送给谁
       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();
  }
}

//你妈给你发包裹,你只需要告诉位置就好。你妈不通知你,你也能接收到包裹,你其实就处在随时监听的状态。你的手机会发短信提醒你,你收到短信就去拿了。


接收端:
//还是要等待客户端的接收!
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);
       
       socker.receive(packet); //阻塞接收
       
       System.out.println(packet.getAddress().getHostAddress());
       System.out.println(new String(packet.getData(),0,packet.getLenght()));
       
       //关闭连接
       socket.close();
  }
}

咨询--UDP聊天实现

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.readBytes();
      DatagramPacket packet = newDatagramPacket(datas,0,datas.lengh,new InetSocketAddress("localhost",6666));
       
      socket.send(packet);
           if(data.equals("bye").trim()){
               break; //本地退出
          }
      }
       socket.close();
  }
}


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 = newDatagramPacket(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").trim()){
               break; //远程退出
          }
      }
       socket.close();
  }
}

改造--UDP多线程在线咨询

在线咨询:两个人都可以是发送方,也都可以是接收方!

public class TalkSend implements Runnable{
   DatagramSocket socket = null;
   BufferedReader reader = null;
   
   private int fromPort;
   private String toIP;
   private int toPort;
   
   public TalkSend(int fromPort,String toIP,int toPort){ //初始化数据要放在构造器内
       this.fromPort = fromPort;
       this.toIP = toIP;
       this.toPort = toPort;
       
       try{
           socket = new DatagramSocket(fromPort);
           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.readBytes();
      DatagramPacket packet = newDatagramPacket(datas,0,datas.lengh,new InetSocketAddress(this.toIp,this.toPort));
       
      socket.send(packet);
          if(data.equals("bye").trim()){
              break; //本地退出
          }catch(Exception e){
              e.printStackTrace();
          }
          }
      }
       socket.close();
  }
}


public class TalkReceive implements Runnable{
   DatagramSocket socket = null;
   private int port;
   private String msgFrom;
   
   public TalkReceive(int port,String msgFrom){
       this.port = port;
       this.msgFrom = msgFrom;
       try{
           socket = new DatagramSocket(port);
      }catch(Exception e){
           e.printStackTrace();
      }
  }
   
   @Override
   public void run(){
       
       while(true){
      try{
            //准备接受包裹
      byte[] container = new byte[1024];
      DatagramPacket packet = newDatagramPacket(container,0,container.length);
          socket.receive(packet); //阻塞式接收包裹
           
          //断开连接 bye
          byte[] data = packet.getData();
          String receiveData = new String(data,0,data.length);
           
          System.out.println(msgFrom+":"+receiveData);
           
          if(receiveData.equals("bye").trim()){
              break; //远程退出
          }
      }catch(IOException e){
          e.printStackTrace();
      }
      }
       socket.close();
  }
}


public class TalkStudent{
   public static void main(String[] args){
       //开启两个线程
       new Thread(new TalkSend(7777,"localhost",9999)).start();
       new Thread(new TalkReceive(8888,"老师")).start();
  }
}

public class TalkTeacher{
   public static void main(String[] args){
       //开启两个线程
       new Thread(new TalkSend(5555,"localhost",8888)).start(); //Thread静态代理的Runnable接口
       new Thread(new TalkReceive(9999,"学生")).start();
  }
}
   

URL下载网络资源

  1. https://www.baidu.com/

    统一资源定位符:定位资源的,定位互联网上的某一个资源

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

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.getProtocal()); //协议
        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()); //参数
    }
}

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/0b9b6527b718aa223af92bd52aa2424f.m4a");
       
       //2.连接到这个资源,用HTTP连接
       HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
       
       //3.下载
       InputStream inputStream = urlConncetion.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.sidconnect(); //断开连接
  }
}

 

参考链接:https://www.bilibili.com/video/BV1LJ411z7vY?t=9&p=12

posted @   守漠待花开  阅读(123)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
点击右上角即可分享
微信分享提示