zoukankan      html  css  js  c++  java
  • java网络编程

    1. IP、域名、端口号的概念

    1.1 IP

    IP(Internet Protocol)是互联网的基础协议,其中一个作用就是给互联网中的设备(主机)分配IP地址,以便在互联网中找到某个设备

    以127开头的IP地址称为本地回环地址,比如127.0.0.1 ,表示本机IP地址,主要作用是方便进行本地测试

    数据包是互联网中数据传输的基本单位,IP规定了数据如何分段打包,以及单个数据包如何传输到目标主机,以便各种设备之间可以相互交换数据

    1.2 域名

    IP地址不方便记忆,而域名(Domain Name),是互联网上主机的名称,每个域名都对应了一个IP地址,而且域名方便记忆,所以人们一般使用域名访问某台主机

    localhost表示本地主机的名称,对应127.0.0.1

    DNS(Domain Name System),即域名系统,存放着互联网上所有域名和IP地址的对应关系,当人们使用域名时,就需要先通过DNS查询域名对应的IP地址,然后再使用IP地址找到目标主机

    计算机中的hosts文件是一个本地的DNS(C:WindowsSystem32driversetc目录下),我们可以修改hosts文件手动配置域名和IP地址的对应关系,计算机在查找时会优先查找hosts文件

    1.3 端口号

    一台主机可以提供多种服务(运行多个程序),为了方便外界区分和访问,每个服务都要有一个端口号,通过IP地址和端口号来唯一确定某台主机上的某个服务

    端口号的范围是 [ 0 , 65535 ] ,其中 [ 0 , 1023 ] 是系统保留端口,提供给系统服务以及其他著名的服务如HTTP(80)。我们自己的程序如果不提供著名服务,就尽量不要占用系统保留端口

    主机中某个端口号某个时刻只能被一个程序占用,系统采用先申请先得的方式进行分配,程序结束即释放所占用的端口号

    某个端口号有时候会被其他程序占用,或者程序重复启动时也会报端口号被占用的错误,这时可以在cmd命令行执行netstat  -ano 查看占用某个端口号的程序的进程id,然后到任务管理器中找到该进程结束掉即可

    2. TCP

    TCP(Transmission Control Protocol)传输控制协议,是一个面向连接的,可靠的,基于字节流的传输层通信协议,很多应用层协议都建立在TCP之上,程序也可直接使用TCP进行网络通信。

    TCP会在两台主机之间建立一个连接(虚拟的),通过一定的方式控制数据传输的过程,可以保证数据的完整、有序、正确

    3. Socket编程

    网络编程,主要是指基于TCP的网络通信编程,使用Socket类实现,也称为socket编程

    socket编程模型中有服务器端和客户端,服务器端使用ServerSocket创建,一般有固定的IP地址和端口号,方便向外界提供服务。客户端可以有多个,并且使用Socket主动连接服务器。连接后,服务器端也创建一个Socket对象表示这次连接

     

    编程步骤:

    服务器端:

    1 创建服务器对象ServerSocket

    2 等待客户端的连接请求,收到请求后即返回表示这次连接的Socket对象

    3 开启新的线程专门处理这个连接

    4 获得连接的输入输出流,并按照一定的规则进行数据交换

    5 关闭连接(关闭连接时会自动关闭IO流)

    客户端:

    1 创建Socket对象,即向服务器申请连接

    2 获得连接的输入输出流,并按照一定的规则进行数据交换

    3 最后关闭连接(关闭连接时会自动关闭IO流)

    平时编程时一般都是基于应用层协议,比如HTTP,直接进行socket编程的并不多。但由于socket编程属于基础层面的重要技术,要求务必掌握

    public class Server1 {
    
        public static void main(String[] args) throws IOException {
    
            ServerSocket server = new ServerSocket(10001);
            Socket socket = server.accept();
    
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();
    
            byte[] data = "hello".getBytes();
            outputStream.write(data);
    
            socket.close();
        }
    }
    public class Client1 {
    
        public static void main(String[] args) throws IOException {
    
            Socket socket = new Socket("localhost", 10001);
    
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();
    
            byte[] buff = new byte[1024];
            int len = inputStream.read(buff);
            System.out.println(new String(buff, 0, len));
            socket.close();
        }
    }

     执行步骤:

    1.运行Server1

    2.运行Client1

    3.输出

    hello
    

    3.1 基于Socket实现字符串翻转服务器

    /*
     *  把从客户端读取到的一行数据的字符进行翻转,然后发送给客户端
     *  当读取到over时,连接断开
     */
    public class Server2 {
    
        public static void main(String[] args) {
    
            try {
                ServerSocket server = new ServerSocket(10002);
    
                while (true) {
                    Socket socket = server.accept();
                    MyThread myThread = new MyThread(socket);
                    myThread.start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    class MyThread extends Thread {
        private Socket socket;
    
        public MyThread(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                String line = null;
                while ((line = bufferedReader.readLine()) != null) {
                    if ("over".equalsIgnoreCase(line)) {
                        break;
                    }
    
                    //字符翻转的操作
                    char[] chs = line.toCharArray();
    
                    for (int i = 0; i < chs.length / 2; i++) {
                        char ch = chs[i];
                        chs[i] = chs[chs.length - 1 - i];
                        chs[chs.length - 1 - i] = ch;
                    }
    
                    bufferedWriter.write(chs);
                    bufferedWriter.newLine();
                    bufferedWriter.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    }
    View Code-字符串翻转服务端
    public class Client2 {
        public static void main(String[] args) {
            Socket socket = null;
            Scanner scanner = null;
            try {
                socket = new Socket("localhost", 10002);
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    
                scanner = new Scanner(System.in);
                String line = null;
                while ((line = scanner.nextLine()) != null) {
                    bufferedWriter.write(line);
                    bufferedWriter.newLine();
                    bufferedWriter.flush();
                    line = bufferedReader.readLine();
                    if (line == null) {
                        break;
                    }
                    System.out.println(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (socket != null) {
                        socket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (scanner != null) {
                    scanner.close();
                }
            }
        }
    }
    View Code-字符串翻转客户端

    4. 基于UDP的网络编程

    传输层协议除了TCP,还有UDP(User Datagram Protocol),即用户数据报协议。UDP是无连接的,而且不保证数据的完整、有序,但传输效率非常高,适合视频、音频等对数据可靠性要求不太高的场景

    UDP编程的时候没有典型的服务器——客户端结构,而且通信的两端不建立连接,可以直接把数据封装成数据包发送到另一端,而且每一端都可以发送、接收数据包

    DatagramSocket 表示通信的一端,可以发送、接收数据包

    DatagramPacket 数据包,理论上一个数据包可包含的数据量最多为65535字节

    public class Send1 {
    
        public static void main(String[] args) throws IOException {
            DatagramSocket sendSocket = new DatagramSocket(10003);
            byte[] data = "hello".getBytes();
            DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 10004);
            sendSocket.send(packet);
            sendSocket.close();
        }
    }
    View Code-send1
    public class Receive1 {
    
        public static void main(String[] args) throws IOException {
            DatagramSocket receiveSocket = new DatagramSocket(10004);
            byte[] buff = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buff, buff.length);
            receiveSocket.receive(packet);
            int len = packet.getLength();
            System.out.println(new String(buff, 0, len));
            receiveSocket.close();
        }
    }
    View Code-received
  • 相关阅读:
    Digital Video Stabilization and Rolling Shutter Correction using Gyroscope 论文笔记
    Distortion-Free Wide-Angle Portraits on Camera Phones 论文笔记
    Panorama Stitching on Mobile
    Natural Image Stitching with the Global Similarity Prior 论文笔记 (三)
    Natural Image Stitching with the Global Similarity Prior 论文笔记(二)
    Natural Image Stitching with the Global Similarity Prior 论文笔记(一)
    ADCensus Stereo Matching 笔记
    Efficient Large-Scale Stereo Matching论文解析
    Setting up caffe on Ubuntu
    Kubernetes配置Secret访问Harbor私有镜像仓库
  • 原文地址:https://www.cnblogs.com/renjing/p/socket.html
Copyright © 2011-2022 走看看