网络编程

本文深入探讨了网络通信的基础知识,包括IPv4和IPv6地址、端口号的概念及其作用,以及TCP和UDP协议的区别。通过Java代码示例展示了如何使用InetAddress类获取IP地址和主机名,并演示了UDP和TCP通信的基本原理。此外,还介绍了文件上传的TCP实现以及服务端多线程优化策略。

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

网络的三要素

ip地址:表示网络中设备的唯一标识
    ipv4: 由4个字节组成,采用点分十进制表示法
        举例:192.168.66.202
	ipv6: 由16个字节组成,采用冒分十六进制表示法
        举例:fb34:66:77:ac:3f
	
    常用的命令:
        ipconfig: 查看本机的ip地址
        ping: 检测网络和指定的ip是否连通

端口号:表示某一台主机上应用程序的表示,是一个[0,65535]范围内的整数。
       0~1023的端口号可能会被占用,建议使用1024之后的端口号。

协议:网络中数据传输的规则
       UDP: 面向无连接的,不安全的协议,每次传输64KB的数据
	   TCP: 面向有连接,安全的协议,传输数据的大小没有限制。

InetAddress类

public static InetAddress getByName(String host) 
    在给定主机名的情况下确定主机的 IP 地址。
public String	getHostAddress() 
	返回 IP 地址字符串(以文本表现形式)举例:"192.168.83.44"
public String	getHostName() 
    获取此 IP 地址的主机名。
//获取ip地址对象
InetAddress inetAddress = InetAddress.getByName("192.168.83.192");

//获取主机地址
String address = inetAddress.getHostAddress(); 

//获取主机名
String hostName = inetAddress.getHostName();

UDP通信

UDP发送端

1.创建DatagramSocket对象(码头)
2.创建DatagramPacket对象(包裹)
    需要制定ip地址和端口号
3.调用send方法,发送数据(把包裹交给码头)
4.调用close方法,释放资源(关闭码头)


public class Sender {
    public static void main(String[] args) throws IOException {
        //1.创建DatagramSocket对象(码头)
        DatagramSocket ds=new DatagramSocket();

        //2.创建DatagramPacket对象(包裹)
        //准备发送的数据
        System.out.println("请输入要发送的数据:");
        String str = sc.next();
        byte[] bs=str.getBytes();
        //发送数据的长度
        int len=bs.length;
        //指定接收的ip地址
        String ip="127.0.0.1";
        //指定接收的端口号
        int port=10086;
        DatagramPacket packet=new DatagramPacket(bs,len, InetAddress.getByName("127.0.0.1"),port);

        //3.调用send方法,发送数据(把包裹交给码头)
        ds.send(packet); 

        //4.调用close方法,释放资源(关闭码头)
        ds.close();
    }
}

UDP接收端

public class Receiver {
    public static void main(String[] args) throws IOException {
        //1.创建DatagramSocket对象(码头)
        DatagramSocket ds=new DatagramSocket(10086);
     
        //2.创建DatagramPacket对象(新的包裹)
        byte[] bs=new byte[1024];
        DatagramPacket packet=new DatagramPacket(bs,bs.length);

        //3.接收数据,存入包裹
        ds.receive(packet); //阻塞,等待发送端发送数据

        //4.打开包裹,获取数据
        byte[] data = packet.getData(); //获取字节数组
        int length = packet.getLength();    //获取数据的实际长度
        InetAddress address = packet.getAddress(); //获取发送端的ip地址
        //把接收到的数据转换为字符串
        String str=new String(data,0,length);
        System.out.println(address.getHostAddress()+"...."+str);
        

        //5.释放资源
     	ds.close();
    }
}

三种通信方式

单播:一个发送端 发给 一个接收端
	使用DatagramSocket进行发送和接收 

组播:一个发送端 发给 多个接收端(一组)
	//创建MulticastSocket对象
    MulticastSocket ms=new MulticastSocket(10000);
	//把当前地址加入组: 组播地址:224.0.1.0
    ms.joinGroup(InetAddress.getByName("224.0.1.0"));
	
广播:一个发送端 发给 所有接收端
	//广播地址:255.255.255.255
	使用DatagramSocket进行发送和接收

TCP通信

TCP通信的基本原理

 

客户端

public class TCPClient {
    public static void main(String[] args) throws IOException {
        //创建Socket对象,指定服务端的ip地址和端口号
        Socket socket=new Socket("127.0.0.1",10086);

        //获取输出流
        OutputStream out = socket.getOutputStream();
        //网服务端写数据
        out.write("你好世界".getBytes());
        //告诉服务端,写完了。
        socket.shutdownOutput();

        //获取输入流
        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String s = br.readLine();
        System.out.println(s);

        //释放资源
        socket.close();
    }
}

服务端

public class TCPServer {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象
        ServerSocket server=new ServerSocket(10086);
        //监听客户端(迎宾)
        Socket socket = server.accept(); //阻塞

        //获取输入流
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        int len;
        while ((len=in.read(bs))!=-1){
            String str=new String(bs,0,len);
            System.out.println(str);
        }

        //获取输出流
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("HelloWorld");
        bw.newLine(); //换行
        bw.flush();

        //释放资源
        socket.close();
        server.close(); 
    }
}

文件上传案例

 

客户端

public class UploadClient {
    public static void main(String[] args) throws IOException {
        //创建Socket对象,绑定服务端的ip和端口号
        Socket socket=new Socket("127.0.0.1",10010);

        //获取通往服务端的输出流
        OutputStream out = socket.getOutputStream();

        //读取本地的a.jpeg图片
        FileInputStream fis=new FileInputStream("day15/a.jpeg");
        byte[] bs=new byte[1024];
        int len; //记录每次读取的字节个数
        while ((len=fis.read(bs))!=-1){
            //把读取到的数据写到服务端
            out.write(bs,0,len);
        }
        //告诉服务端数据写完了
        socket.shutdownOutput();

        //获取服务端返回的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String s = br.readLine();
        System.out.println(s);

        //释放资源
        socket.close();
    }
}

服务端

public class UploadServer {
    public static void main(String[] args) throws IOException {
        //创建服务端ServerSocket对象,绑定端口号
        ServerSocket server=new ServerSocket(10010);

        //监听客户端
        Socket socket = server.accept();
		
        //创建本地输出流
        File filename=new File("/Users/itheima/Desktop/upload", UUID.randomUUID()+".jpeg");
        FileOutputStream fos=new FileOutputStream(filename);

        //获取读取网络数据的流
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        int len; //记录每次读取的字节个数
        while ((len=in.read(bs))!=-1){
            //把读取到的数据写到服务端
            fos.write(bs,0,len);
        }
        fos.close();

        //往服务端写一个反馈信息"上传成功"
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("上传成功");
        bw.newLine();
        bw.flush();

        socket.close();
        server.close();
    }
}

服务端多线程优化

/*
图片上传的线程任务
 */
public class UploadRunnable implements Runnable {

    private Socket socket;

    public UploadRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            //创建本地输出流
            File filename=new File("/Users/itheima/Desktop/upload", UUID.randomUUID()+".jpeg");
            FileOutputStream fos=new FileOutputStream(filename);

            //获取读取网络数据的流
            InputStream in = socket.getInputStream();
            byte[] bs=new byte[1024];
            int len; //记录每次读取的字节个数
            while ((len=in.read(bs))!=-1){
                //把读取到的数据写到服务端
                fos.write(bs,0,len);
            }
            fos.close();

            //往服务端写一个反馈信息"上传成功"
            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write("上传成功");
            bw.newLine();
            bw.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

死循环监听客户端,不断的处理文件上传的任务

public class UploadServer {
    public static void main(String[] args) throws IOException {
        //创建服务端ServerSocket对象,绑定端口号
        ServerSocket server=new ServerSocket(10010);

        while (true){
            //监听客户端
            Socket socket = server.accept(); //阻塞
            //创建线程并执行
            new Thread(new UploadRunnable(socket)).start();
        }

        //server.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值