Java网络编程通信协议、三要素、客户端服务器端代码实现,上传下载文件

1、网络通信协议分类

  • TCP/IP是Internet最基本,最广泛的协议,在TCP协议中,客户端和服务器端有3次交互,以保证连接的可靠

    • 第一次握手:客户端向服务器端发送请求连,等待服务器端确认。
    • 第二次握手:服务器端向客户端回送一个响应,通知客户端收到了一个请求连接
    • 第三次握手:客户端再次向服务器发送确认信息,确认连接
  • UDP(用户数据报协议:User Datagram Protocol),UDP是无连接通信协议,即在数据传输的时候数据的发送端和接受端不建立逻辑链接。简单的说,当一台计算机向另一台计算机发送数据时,发送端不会确认接收端是否存在就会发送数据,同样接收端接收到数据后也不会向发送端反馈接收到数据

    UDP特点:耗资小,通信效率高,一般音频,视频传输都会用到UDP协议,比如视频会议,偶尔会丢失一俩个数据包,发送的数据会限制在64K以内。

2、网络编程三要素

  • 协议
  • IP地址
  • 端口

3、TCP通信的概述

客户端和服务器端进行一次数据交互,需要4个IO对象,(字节流对象)

服务器端必须明确俩件事情
  1. 多个客户端同时和服务器进行交互,服务器必须明确和哪个进行交互,在服务器端有一个方法accept,获取到请求的客户端对象
  2. 多个客户端同时和服务器进行交互,需要使用多个IO流和客户端进行交互。服务器使用客户端的字节输入流读取客户端发送的数据,服务器使用客户端的字节输出流给客户端回写数据。

4、TCP客户端,服务器端实现

  • 客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient {
    /*
    * TCP通信客户端:请求服务器向其发送数据,读取服务器返回的数据
    * 表示客户端的类:java.net.Socket
    *
    * 成员方法:
    *   OutputStream getOutputStream(),返回此套接字的输出流
    *   InputStream getInputStream()
    *
    * 注意:
    *   1、客户端和服务器进行交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象
    *   2、当客户端和服务器3次握手连接建立连接通路时,如果服务器没有启动会抛出异常
    *  */

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",9999);

        //向服务器发送
        OutputStream os = socket.getOutputStream();
        os.write("Hello Server".getBytes());

        InputStream is = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println("读取到服务器会写数据:" + new String(bytes,0,len));

        socket.close();
    }

}

  • 服务器端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {

    /*
    * TCP通信的服务器端
    * java.net.ServerSocket
    * */

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(9999);
        System.out.println("等待连接...");
        //获取请求的客户端对象socket
        Socket socket = server.accept();
        InputStream is = socket.getInputStream();

        //读取客户端的发送的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println("读取到客户端发送数据:" + new String(bytes,0,len));


        //向客户端发送数据,(需要从获取的客户端的socket对象中获取流对象,而不能自己写流对象)
        OutputStream os = socket.getOutputStream();
        os.write("OK,Thanks".getBytes());

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

    }
}

5、TCP文件上传

注意:客户端和服务器在本地硬盘读写需要使用自己创建的字节流对象(本地流)
客户端和服务器之间的读写需要使用Socket中提供的字节流对象(网络流)

  • TCP文件上传服务器端:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPFileServer {

    public static void main(String[] args) throws IOException {
        //创建服务器的ServerSocket对象
        ServerSocket server = new ServerSocket(9898);
        //获取请求客户端的socket对象
        Socket socket = server.accept();
        InputStream is = socket.getInputStream();

        File file = new File("/Users/ydsungan/upload");
        if(!file.exists()){
            file.mkdirs();
        }

        //创建本地字节输出流
        FileOutputStream fos = new FileOutputStream(file + "/test2.pdf");

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = is.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }

        socket.getOutputStream().write("上传成功".getBytes());

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

  • 文件上传客户端
import java.io.*;
import java.net.Socket;

public class TCPFileClient {
    public static void main(String[] args) throws IOException {
        //创建本地字节输入流
        FileInputStream fis = new FileInputStream("/Users/ydsungan/Documents/文档/test.pdf");

        //创建客户端的socket对象
        Socket socket = new Socket("127.0.0.1",9898);
        OutputStream os = socket.getOutputStream();

        //读取本地文件
        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!=-1){
            os.write(bytes,0,len);
        }
        //给服务器写一个终止符
        socket.shutdownOutput();

        InputStream is = socket.getInputStream();
        while((len = is.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }

        fis.close();
        socket.close();

    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值