软件结构

C/S结构
全称为Client/Server结构,指客户端和服务端结构,常见的程序:QQ、迅雷

B/S结构
全称为Browser/Server结构,指浏览器和服务器结构,常见的有谷歌、火狐

网络编程
就是在一定的协议下,实现两台计算机之间的通讯

网络通讯协议

网络通讯协议
通过计算机网络使多台计算机实现连接,位于同一网络中的计算机在进行连接和通讯时要遵守一定的规则。

TCP/IP协议
传输控制协议/因特网互联协议,是internet最基本、最广泛的协议

协议分类

  • UDP:用户数据报协议,无连接通讯协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接
    简单来说就是发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到
    特点:消耗资源小、通讯效率高、数据限制在64kb内超出就不能发送了
    使用范围:常用于音频、视频和普通数据的传输
    数据报:数据传输的基本单位
  • TCP:传输控制协议,TCP协议是面向连接的通信协议,在传输数据前发送端与接收端要进行逻辑链接,他提供了两台计算机之间无差错的数据传输
    特点:安全,适用于网页浏览等
    在TCP连接中必须要明确客户端与服务端,由客户端发出连接请求,经过三次握手连接
    • 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器的三次交互,以保证连接的可靠性
      • 第一次握手:客户端向服务器发出连接请求,等待服务器确认
      • 第二次握手:服务端向客户端回送一个响应,通知客户端收到了连接请求
      • 第三次握手:客户端向服务端发送连接信息,确认连接

网络编程三要素(协议、IP地址、端口号)

协议

  • 计算机网络通讯必须遵守的规则

IP地址

  • 互联网协议地址,用ip给互联网中的计算机做唯一的编号
  • IPv4:是一个32位进制数,通常被分为4个字节,表示成a.b.c.d,其中a、b、c、d都是0~255之间的十进制数,最多表示42亿个
  • IPv6:采用128位地址长度,每16个字节为一组,分成8组16进制数,可以为每一粒沙子编上一个地址

常用命令

  • 查看本机IP地址
    ipconfig
  • 检查网络连通性
    ping 空格 IP地址
    ping www.baidu.com

    端口号

  • 是一个逻辑端口我们无法看到可以使用一些软件进行查看
  • 当我们打开一个网络软件,那么操作系统就会为网络软件分配一个端口号
  • 端口号由两个字节组成,范围:0~65535之间

注意

  • 1024之前的端口号不能使用,已经被系统分配给网络软件了
  • 网络端口号不能重复

常见端口

  1. 80端口:网络端口
  2. 数据库 mysql:3306 Oracle:1521
  3. Tomcat服务器:8080

TCP通信程序

TCP通信能实现两台计算机之间的数据交换,通信的两端,要严格区分客户端(Client)和服务端(Server)

两端通信的步骤:

  1. 服务端程序,需要事先启动,等待服务端连接
  2. 客户端主动连接服务端,连接成功才能通信,服务端不会主动连接客户端

实现TCP通信的两个类

  1. 客户端:java.net.Socket类表示,创建Socket对象,向服务端发送连接请求,服务端响应请求,两者建立连接开始通信
  2. 服务端:java.net.SeverSocket类表示,创建ServerSocket对象,相当于开启一个服务,并等待客户端连接

    Socket类

    此类实现客户端套接字,套接字是两个机器通信的端点
    套接字:包含IP地址和端口号的网络单位

构造方法
Socket(String host,int port)创建一个流套接字并将其连接到指定主机的指定端口。
参数:

  • String host:服务器主机的名称/IP地址
  • int port:服务器的端口号

成员方法

  • OutputStream getOutputStream():返回此套接字的输出流
  • InputStream getInputStream():返回此套接字的输入流
  • void close():关闭此套接字

实现步骤

  1. 创建一个客户端对象Socket,构造方法绑定服务器IP地址和端口号

  2. 使用方法getOutputStream(),获取网络字节输出流OutputStream

  3. 使用网络字节输出流的方法write,给服务器发送数据

  4. 使用方法getInputStream(),获取网络字节输入流InputStream对象

  5. 使用方法read,读取服务器回写的数据

  6. 释放资源

     import java.io.InputStream;
     import  java.io.OutputStream;
     import java.io.IOException;
     import  java.net.Socket;
     /**
      * @ClassName: TCPClient
      * @Author: 双g
      * @Date: 2019/10/18 12:53
      */
     public class TCPClient {
         public static void main(String[] args) throws IOException {
             Socket socket = new Socket("127.0.0.1",8888);
    
             OutputStream out = socket.getOutputStream();
    
             out.write("你好服务器!".getBytes());
    
             InputStream is = socket.getInputStream();
    
             byte [] buffer = new byte [1024];
             int len = is.read(buffer);
    
             System.out.println(new String(buffer,0,len));
    
             socket.close();
         }
     }

SeverSocket类

此类实现服务器套接字
构造方法
ServerSocket(int port)创建绑定到特定端口的服务器套接字
服务端必须明确一件事情,必须知道是哪个客户端请求的服务器
可以使用accept方法获取到请求的客户端对象Socket
成员方法

  • Socket accept()倾听并接收此套接字的连接

实现步骤

  1. 创建服务器ServerSocket对象和系统指定的端口号
  2. 使用方法accept,获取到请求的客户端Socket
  3. 使用方法getInputStream()获取字节输入流
  4. 使用方法read,读取客户端发送的数据
  5. 使用getOutputStream()获取字节输出流
  6. 使用方法write,给客户端写回话
  7. 释放资源
import  java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import  java.net.ServerSocket;
import java.net.Socket;
/**
 * @ClassName: TCPSever
 * @Author: 双g
 * @Date: 2019/10/18 13:15
 */
public class TCPSever {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8888);

        Socket socket = ss.accept();

        InputStream is = socket.getInputStream();

        byte [] buf = new byte [1024];
        int len = is.read(buf);
        System.out.println(new String(buf,0,len));

        OutputStream os = socket.getOutputStream();

        os.write("收到谢谢!".getBytes());

        socket.close();

        ss.close();
    }
}  

TCP通信文件上传案例

原理:客户端读取本地的文件,把文件上传到服务器,服务器把上传的文件保存到服务器的硬盘
步骤:

  • 客户端使用本地字节输入流,读取要上传的文件
  • 客户端使用网络字节输出流,把读取的文件上传到服务器
  • 服务器使用网络字节输入流,读取上传的文件
  • 服务器使用本地字节输入流,把读取的文件保存到服务器的硬盘上
  • 服务器使用网络字节输出流,给客户端回写一个"上传成功"
  • 客户端使用网络字节输入流,读取服务器回写的数据
  • 释放资源

注意:客户端和本地硬盘进行读写,需要使用自己创建的字节流对象(本地流)
        客户端和服务器进行读写操作,必须用Socket中提供的字节流对象(网络流)
例:
服务端:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import  java.net.ServerSocket;
import java.io.FileOutputStream;
import java.net.Socket;
/**
 * @ClassName: FileUploadTcpServer
 * @Author: 双g
 * @Date: 2019/10/20 22:53
 */
public class FileUploadTcpServer {
    public static void main(String[] args) throws IOException {
        //创建TCP服务端                                
        ServerSocket ss = new ServerSocket(8888);
        Socket socket = ss.accept();
        //接收文件
        InputStream in = socket.getInputStream();
        //定义一个输出流对象
        FileOutputStream fl = new FileOutputStream("C:\\gost.jpg");
        //read写入文件到硬盘
        int len = 0;
        byte [] buf = new byte [1024];
        while ((len = in.read(buf))!=-1){
            fl.write(buf,0,len);
        }
        //通知客户端收到了
        OutputStream out = socket.getOutputStream();
        out.write("上传成功!".getBytes());
        //释放资源
        out.close();
        fl.close();
        ss.close();
        socket.close();
    }
}

客户端:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
 * @ClassName: FileUploadTcpClient
 * @Author: 双g
 * @Date: 2019/10/20 22:40
 */
public class FileUploadTcpClient {
    public static void main(String[] args) throws IOException {
        //创建输入流对象绑定数据源
        FileInputStream fl  = new FileInputStream("E:\\gost.jpg");
        //创建客户端对象
        Socket s = new Socket("127.0.0.1",8888);
        //获取网络字节输出流
        OutputStream out = s.getOutputStream();
        //读取字节
        int len = 0;
        byte [] buf = new byte [1024];
        while ((len = fl.read(buf))!=-1) {
            out.write(buf,0,len);
        }
        //获取服务器返回的对象
        InputStream in = s.getInputStream();
        //使用read读取数据
        while ((len = in.read(buf))!=-1){
            System.out.println(new String(buf,0,len));
        }
        //释放资源
        out.close();
        fl.close();
        in.close();
        s.close();
    }
}
Last modification:May 29th, 2020 at 01:42 pm
如果觉得我的文章对你有用,请随意赞赏