Java网络编程实现本地通信(一)

目录

前言

计算机网络简介

网络编程的目的

网络通信的要素

地址:

交流方式:

URL

IP

IP地址分类

1、公网IP、私网IP

2、ipv4/ipv6

3、本机IP地址

域名

JavaIP地址类:InetAddress

Port

端口号

端口号分类

公有端口:0~1023

程序注册端口:1024~29151

动态私有端口:48152~65535

Windows查看本机端口命令

 Java端口地址类:InetSocketAddress

TCP-UDP协议

简介

TCP实现客户端-服务器通信

TCP实现文件传输

UDP实现客户端-服务器通信

单方向传输

双向通信        

参考


前言

        本系列博客将使用java实现网络通信,利用本地主机建立不同端口模拟通信。本篇文章对网络编程进行简介,并实现TCP&UDP单向通信。

计算机网络简介

        长话短说,计算机网络即通过一定组网技术与通信协议将不同的计算机或其他设备连接起来,以便实现通信、资源共享与其他操作。

网络编程的目的

        实现不同计算机之间的远距离信息通信、数据交换与数据共享。

网络通信的要素

地址:

1、找到通信对象,即定位主机IP(唯一定位主机)。

2、找到需要访问的进程或应用资源,即定位端口(port)。

通过IP+Port的二元组定位两台电脑间程序的通信对象。

交流方式:

        在通信时,需要规定说话的两个人要以什么样的方式交流,否则可能存在 你说我也说、你说我不听、我说你不听、你还没说完我就走了、我还没说完你就走了、你说话怎么这么慢、外人怎么听到我们聊天了 等问题。这就是网络通信协议,如HTTP、TCP、UDP等协议。

推荐文章:

                                一篇文章看明白 TCP/IP,TCP,UDP,IP,Socket 之间的关系https://blog.csdn.net/freekiteyu/article/details/72236734

URL

        URL(uniform resource locator)即唯一资源定位符,由三部分组成:协议、地址和资源。在java的URL类中,协议必须是JVM支持的协议。地址必须是能够链接的网址或者IP,而资源则可以是服务器或主机上的任何文件。详细见下文:

         一文了解URL、IP、域名...https://blog.csdn.net/ambitiousssssss/article/details/122378306?spm=1001.2014.3001.5502

IP

IP地址分类

1、公网IP、私网IP

        如:192.168.1.1,为国家部门专用IP。

        详细分类可见下文:

                                       IP地址分类(ABCDE)https://blog.csdn.net/zhoutianzi12/article/details/103199111

2、ipv4/ipv6

        ipv4:由四个字节组成,如172.02.01.1

        ipv6:8个十六进制无符号整数,每个整数间由 “:” 隔开。如:2022:0b22:aaaa:0016:0000:0001:1111:2222

3、本机IP地址

        127.0.0.1:为本机 (localhost)。

域名

        因为IP地址太难记,便用域名对IP进行替换。如:www.baidu.com、www.jd.com,这一系列域名背后便对应着相应服务器的IP地址。

JavaIP地址类:InetAddress

import java.net.InetAddress;
import java.net.UnknownHostException;

public class IP {
     public static void main(String[] args) throws UnknownHostException {
        try {
            //多种方式打印本机IP//需导入相关包,本文件1、2行
//             InetAddress IpAddress1 = InetAddress.getByName("127.0.0.1");
//             InetAddress IpAddress2 = InetAddress.getByName("localhost");
//             InetAddress IpAddress3 = InetAddress.getLocalHost();
//             System.out.println(IpAddress3);
            //打印京东IP
            InetAddress IpAddress = InetAddress.getByName("www.jd.com");//需导入相关包,本文件1、2行
            System.out.println(IpAddress);
            //InetAddress类常用方法
            System.out.println(IpAddress.getCanonicalHostName());//规范的主机名
            System.out.println(IpAddress.getHostAddress());//ip
            System.out.println(IpAddress.getHostName());//域名,或者本机名称
            
        }catch(UnknownHostException e){
             e.printStackTrace();//抛出相关异常
        }
    }
}

Port

端口号

        通过0~65535这些端口号对一台主机上单个协议下的进程进行唯一表示!不同协议又可分为TCP端口号与UDP端口号。

端口号分类

公有端口:0~1023

        如:HTTP:80、HTTPS:443、FTP:21、SSH:22、Telent:23.

程序注册端口:1024~29151

        分配给用户或程序,如:MySQL:3306、Oracle:1521、Tomcat:8080.

动态私有端口:48152~65535

        系统分配,尽量不主动分配。

Windows查看本机端口命令

        在Windows主机上(Linux可能命令不同),打开cmd,输入:

netstat -ano  #命令行查看端口
netstat -ano |findstr "端口号" #查看指定的端口
tasklist|findstr "进程号" #查看指定进程号的进程

结果如下:

 Java端口地址类:InetSocketAddress

import java.net.InetSocketAddress;

public class PORT {
    public static void main(String[] args) {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",4204);
        InetSocketAddress socketAddress2 = new InetSocketAddress("localhost",4204);
        //print
        System.out.println(socketAddress);
        System.out.println(socketAddress2);
        //返回IP,返回端口
        System.out.println(socketAddress.getAddress());
        System.out.println(socketAddress.getPort());
        System.out.println(socketAddress.getHostName());
        
    }
}

TCP-UDP协议

简介

TCP:可靠的连接性传输协议 。连接方式与断开方式:“三次握手”、“四次挥手”。

UDP:不可靠的传输协议,即无特殊方式保证接收端一定接收数据。

TCP简介如下文:

                                五分钟读懂TCP 协议——TCP协议简介https://blog.csdn.net/ningdaxing1994/article/details/73076795

TCP实现客户端-服务器通信

以下代码实现客户端向服务器发送消息(需先运行服务器,再运行客户端):

客户端代码:

package TCP;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

//客户端
public class TcpClientDemo1 {
    public static void main(String[] args) {

        InetAddress ServerAddress = null;
        Socket socket = null;
        OutputStream os = null;

        try {

            //1、需定位服务器地址
             ServerAddress = InetAddress.getByName("127.0.0.1");
            //2、端口号
            int port = 6170;
            //3、创建一个Socket链接
            socket = new Socket(ServerAddress,port);
            //4、IO流发送消息
            os = socket.getOutputStream();
            os.write("你好,我是客户端!".getBytes(StandardCharsets.UTF_8));

        } 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();
                 }
        }

    }
}

服务器代码:

package TCP;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;

//服务端

public class TcpServerDemo1 {
    public static void main(String[] args) {

        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream is = null;
        ByteArrayOutputStream byteArrayOutputStream =null;

        try {
            //1、创建一个Socket用于与客户端通信
             serverSocket = new ServerSocket(6170);
            //2、监听客户端连接
             accept = serverSocket.accept();
            //3、读取客户端消息
             is = accept.getInputStream();
            /*
                 byte[] buff = new byte[1024];
                 int len;
            while(!((len = is.read(buff)) <= 0)){
                 String msg = new String(buff,0,len);
            }
                 System.out.println(msg);
           */
            //管道流
             byte[] buff = new byte[1024];
             byteArrayOutputStream = new ByteArrayOutputStream();

            int len;
            while(!((len = is.read(buff)) <= 0)){
                byteArrayOutputStream.write(buff,0,len);
            }
                System.out.println(byteArrayOutputStream.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            if (byteArrayOutputStream!=null)
            try {
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

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

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

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

    }
}

运行结果:

TCP实现文件传输

通过客户端向服务器传输本地文件,服务器接收到文件存放在服务器本地。

客户端代码:

package TCP;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

//TCP文件传输客户端
public class TcpClientDemo2 {
    public static void main(String[] args) throws IOException {
        //socket连接服务器
        Socket socket = new Socket("127.0.0.1",9090);
        //创建输出流关联socket
        OutputStream os = socket.getOutputStream();
        //读取文件(位置为根目录下的picture.png)
        FileInputStream fis = new FileInputStream(new File("picture.png"));
        //写出文件
        byte[] buff = new byte[1024];
        int len;
        while(!((len = fis.read(buff)) <= 0)){
            os.write(buff,0,len);//向os写buff的内容
        }
        //关闭资源(此处为简写,正常情况应判断各种资源是否为空,并捕获异常)
        fis.close();
        os.close();
        socket.close();
    }
}

  服务器代码:

package TCP;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

//TCP文件传输服务器
public class TcpServerDemo2 {
    public static void main(String[] args) throws IOException {
        //创建服务端口
        ServerSocket socket = new ServerSocket(9090);
        //监听端口
        Socket accept = socket.accept();
        //读取socket传输的流数据
        InputStream is = accept.getInputStream();
        //文件输出
        FileOutputStream fos = new FileOutputStream("receive_picture");
        int len;
        byte[] buff = new byte[1024];
        while(!((len = is.read(buff)) <= 0)){
            fos.write(buff,0,len);
        }
        //释放资源(按照资源分配顺序,逆序释放)
        fos.close();
        is.close();
        accept.close();
        socket.close();
    }
}

传输结果:

UDP实现客户端-服务器通信

单方向传输

接收端代码:

package UDP;

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

//UDP数据包通信服务器
public class UdpServerDemo1 {
    public static void main(String[] args) throws Exception {
        //1、建立与客户端相同的Socket,开放端口
        DatagramSocket ServerSocket = new DatagramSocket(9090);
        //2、监听端口并接收数据包
        byte[] buff = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buff,0,buff.length);

        ServerSocket.receive(packet);//线程阻塞接收
        System.out.println(packet.toString());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        System.out.println("我来自"+packet.getAddress());
        //3、释放资源
        ServerSocket.close();
    }
}

发送端代码:

package UDP;

import java.net.*;
import java.nio.charset.StandardCharsets;

//UDP数据包通信客户端
public class UdpClientDemo1 {
    public static void main(String[] args) throws Exception {
        //1、建立DatagramSocket
        DatagramSocket socket = new DatagramSocket();
        //2、建立数据包
        String msg = "Hello,server!";
        InetAddress localhost = InetAddress.getByName("127.0.0.1");
        int port = 9090;
        DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
        //3、发送数据包
        socket.send(datagramPacket);
        //4、关闭连接
        socket.close();
    }
}

传输结果:

双向通信        

        将在下一篇文章,将更新实现聊天室。最近事可能比较多...2022-4-29 1:20


参考

        《Java2实用教程》

           狂神说网络编程

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七月是你的谎言..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值