Java基础之网络编程入门篇

本文是Java网络编程基础篇,适合初学者。介绍了网络编程目的、两个关键问题及对应要素(IP和端口号、网络协议),阐述了TCP和UDP协议特点,还给出基于TCP和UDP的网络编程Java实现步骤及代码示例,包含名词解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网络编程(基础阶段了解即可)

本章大纲

此文只是对初学Java小白的基础篇,设计的网络编程知识以及TCP/IP协议深度较浅,请选择性决定是否阅读,对于HTTP等协议感兴趣并想进一步了解的同学可以阅读《图解HTTP》中文版

  • 网络通信要素
  • IP和端口号
  • 网络协议
  • TCP网络编程
  • UDP网络编程

网络编程目的

直接或间接地通过网络协议与其他计算机进行数据交换,进行通讯

网络编程的两个问题

  1. 如何准确的定位网络上的主机,定位到主机的特定的应用
  2. 找到主机后如何可靠高效地进行数据传输

网络编程中的两个要素

  1. 对应问题一:IP和端口号

  2. 对应问题二:提供网络通信协议:TCP/IP

    参考模型

    1. 应用层
    2. 传输层
    3. 网络层
    4. 物理+数据链路层

通信要素一:IP和端口号

IP

  1. IP:唯一的标识 Internet上的计算机(通信实体)

  2. 在Java中用 InetAddress类代表IP

    1.   InetAddress ip1 = InetAddress.getByName("192.168.0.1");
                  InetAddress ip2 = InetAddress.getByName("www.baidu.com");
                  InetAddress ip3 = InetAddress.getByName("localhost");
                  InetAddress ip4 = InetAddress.getLocalHost();
      
  3. IP分类: IPV4&IPV6 局域网&万维网

  4. 域名:www.baidu.com 域名通过DNS解析转到具体的IP地址后再访问

  5. 本地回路地址:127.0.0.1 对应域名localhost

端口号

端口号表示正在计算机上运行的进程

  • 不同的进程有不同的端口号
  • 别规定为一个16位的整数 0-65535
  • 端口分类
    • 公认端口 0~1023
    • 注册端口 1024~49151【如Tomcat-8080 MySQL-3366】
    • 动态/私有端口 49153~65535

端口号和IP地址的组合得出一个网络套接字==–Socket–==

Socket

  • 通信的两端都要Socket,是两台机器通信的端点
  • 网络通信其实就是Socket之间的通信
  • Socket允许程序把网络连接当成一个流,数据在两个Socket之间通过IO传输
  • 一般主动发起通信的应用程序为客户端,等待的为服务端
  • Socket分类
    • Stream Socket 流套接字–使用 TCP提供可依赖的字节流服务
    • Datagram Socket 数据报套接字–使用 UDP 提供数据服务----- 【只管无脑发送】

通信要素二:网络协议

​ TCP&UDP

TCP协议 ==传输控制协议

  • 使用前必须建立连接
  • 传输前,采用三次握手机制【文末解读】
  • 可进行大数据量的传输
  • 传输完毕需要关闭资源,效率低

UDP协议 用户数据报协议

  • 不需要建立连接,将数据、源、目的封装成数据包
  • 每个数据包的大小限制为64k
  • 发送接受不确认,不可靠
  • 无需释放资源,开销小,效率高

基于TCP的网络编程

在这里插入图片描述

java实现步骤

客户端:

  1. 创建socket对象,指明服务器端的IP和端口号
  2. 获取输出流,输出数据
  3. 资源关闭

服务器端:

  1. 创建ServerSocket对象,指明自己的端口号
  2. 调用accept方法接受客户端的socket
  3. 获取输入流,读取数据
  4. 关闭资源

代码实现

附文章最后

感兴趣的同学可以自行编写下面两个题目,我将在后续的blog中更新答案

  • 服务端读取图片发送给客户端,客户端保存到本地
  • 客户端给服务端发送文本,服务端将文本大写后返回给客户端

基于UDP网络编程

  • 类DatagramSocket 和 DatagramPacket 实现了基于UDP 协议的编程
  • UDP数据包通过套接字DatagramSocket发送和接受,但不安全可靠
  • DatagramPacket对象封装了UDP数据报,在数据报中发送了包含发送端IP地址和端口号以及接收端地址和端口号
  • UDP协议中,每个数据报都给出了完整的地址信息,so无需建立发送和接受

代码实现附文末

名词解释

三次握手 用于传输资源前的连接确认

客户端 A 服务器端 B

A:我来了,我要开始了

B:你来吧

A:那我来了

四次挥手 用于关闭连接

A:我要走

B:好的

B:你走了吗

A:我走了

TCP编程代码实现

​ 基础Demo1

此处代码使用JUnit,也可以分开单独写成两个类

public class TcpDemo1 {
    @Test
    public void ServerTask (){
        
        ServerSocket serverSocket =null;
        Socket sss = null;
        InputStream isr = null;
        ByteArrayOutputStream baos = null;
        try{
            //1. 调用ServerSocket(int port) 创建套接字,绑定到指定端口,开始监听,此处为了关闭资源安全,将其提前声明在try catch外
            serverSocket = new ServerSocket(8899);
            //2. 调用accpet监听请求连接,如果客户端请求连接,则接受,反之,返回套接字对象
            sss = serverSocket.accept();
            //调用socket类的输入流
            isr = sss.getInputStream();
            baos = new ByteArrayOutputStream();
            byte []cache = new byte[3];
            int readnum = 0;
            while ((readnum=isr.read(cache))!=-1){
                baos.write(cache,0,readnum);
            }
            System.out.println(baos.toString());
            System.out.println();
            
        }catch(Exception e){
                e.printStackTrace();
                System.out.println("Exception");
        }finally {
            try{//4. 关闭流,一定要释放资源
                baos.close();
                isr.close();
                sss.close();
                serverSocket.close();    
            }catch(Exception e){
                    e.printStackTrace();
                    System.out.println("Exception");
            }
        }
    }
@Test
    public void ClientTask(){
        Socket socket = null;
        OutputStream os = null;
        try{
            //1. 创建socket 绑定IP和端口号
            socket = new Socket("localhost",8899);
            //2. 打开socket的流 此处为输出流
            os  = socket.getOutputStream();
            //3. 进行流的读写操作
            os.write("hello world".getBytes());



        }catch(Exception e){
                e.printStackTrace();
                System.out.println("Exception");
        }finally {
            try{
                //4. 关闭流,一定要释放资源
                socket.close();
                os.close();

            }catch(Exception e){
                    e.printStackTrace();
                    System.out.println("Exception");
            }
        }
    }
}

Dem2

//此案例容易bug的地方位于,read为阻塞方法,具体在代码中有解释


//客户端发送文件给服务端,服务端保存在本地,并返回成功语句
public class TcpPrintConsle {
    @Test
    public void Server1(){
        ServerSocket sscoket1 = null;
        Socket socket1 = null;
        InputStream is = null;
        FileOutputStream fos = null;
        OutputStream os = null;
        try{
           sscoket1 = new ServerSocket(9999);
           socket1 = sscoket1.accept();
           is = socket1.getInputStream();
           fos = new FileOutputStream("c:/tcp.jpg");
            byte []cache = new byte[1024];
            int readnum = 0 ;
            while ((readnum=is.read(cache))!=-1){
                fos.write(cache,0,readnum);
            }

//----发送成功的消息返回客户端-----
            os = socket1.getOutputStream();
           os.write("接收成功".getBytes());

        }catch(Exception e){
                e.printStackTrace();
                System.out.println("Exception");
        }
        finally {
            try{
                is.close();
                socket1.close();
                sscoket1.close();

            }catch(Exception e){
                    e.printStackTrace();
                    System.out.println("Exception");
            }
        }
    }

    @Test
    public void Client1(){
        try{
            Socket socket = new Socket("127.0.0.1",9999);
            OutputStream os = socket.getOutputStream();
            FileInputStream fis = new FileInputStream("c:/test.png");
            int readnum = 0 ;
            byte []cache = new byte[1024];

            while ((readnum=fis.read(cache))!=-1){
                os.write(cache,0,readnum);
            }

            //告诉服务器已经结束传输,不然服务器会一直处于read状态,一直while循环中
            socket.shutdownOutput();
            
            //========接收
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            InputStream is = socket.getInputStream();
            int len = 0;
            byte []buffer = new byte[1024];
            while ((len=is.read(buffer))!=-1){
                baos.write(buffer,0,len);
            }
            System.out.println(baos.toString());
            os.close();
            fis.close();
            socket.close();
        }catch(Exception e){
                e.printStackTrace();
                System.out.println("Exception");
        }finally {
        }
    }
}

UDP编程代码实现

 @Test
//发送端
    public void Sender(){
        DatagramSocket ds = null;
        try{
                ds = new DatagramSocket();
                byte []txt = "hello world ".getBytes();
                DatagramPacket dp = new DatagramPacket(txt,0,txt.length, InetAddress.getByName("127.0.0.1"),6868);
                ds.send(dp);

        }catch(Exception e){
                e.printStackTrace();
                System.out.println("Exception");
        }finally {
            try{

                    ds.close();
            }catch(Exception e){
                    e.printStackTrace();
                    System.out.println("Exception");
            }
        }

    }
 @Test
 //接收端
    public void Receiver(){
        DatagramSocket ds = null;
        try{
                ds = new DatagramSocket(6868);
                byte []txt = new byte[1024];
                DatagramPacket dp = new DatagramPacket(txt,txt.length);
                ds.receive(dp);
                String str = new String(dp.getData(),0,txt.length);
            System.out.println(str);
        }catch(Exception e){
                e.printStackTrace();
                System.out.println("Exception");
        }
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值