Java之网络编程

网络编程

概述

  • 网络编程 : 通过编程实现不同计算机间数据的共享
  • C/S : 客户端/服务器模式
    1. 好处:部分代码放在客户端,访问服务器只需要传输有效的数据.
    2. 弊端:必须安装客户端,并且服务器升级,对应的客户端必须升级.
  • B/S : 浏览器/服务器模式
    1. 好处:不需要安装客户端,不需要考虑服务器升级问题.
    2. 弊端:所有的数据都在服务器,网络不好,反应慢,不友好.

网络编程三要素

  1. 协议 : 计算机与计算机之间传输的规则(协议的三要素如下)
    1. 语法,就是这一段内容要符合一定的规则和格式。例如,括号要成对,结束要使用分号等。
    2. 语义,就是这一段内容要代表某种意义。例如数字减去数字是有意义的,数字减去文本一般来说就没有意义。
    3. 顺序,就是先干啥,后干啥。例如,可以先加上某个数值,然后再减去某个数值。
  2. IP地址 : 在网络中,ip地址是唯一标识
  3. 端口号 : 计算机中应用程序的唯一标识

客户端的代码步骤

  1. 创建Socket的对象,指定ip地址和端口号
  2. 利用socket获取文件字节输出流对象(可以使用转换流将字节流转化为打印流)
  3. 利用字节流向服务端发送消息
  4. 关闭socket资源

服务端的代码步骤

  1. 创建ServerSocket对象,设置端口号
  2. 利用创建的ServerSocket对象使用sccept方法获取Socket对象
  3. 利用第二步获取的socket获取字节输入流对象(可以只用转换流将字节流转化为字符高效流)
  4. 使用第三步的流读取客户端发送的信息
  5. 关闭资源

在整个过程中,需要注意的是随时刷新缓冲区和关闭流,所以推荐使用打印流,会自动刷新和自动换行.

写个小例子,实现客户端和服务端的单次通信

package homework.demo5;

import java.io.*;
import java.net.Socket;

/**
 * 创建客户端
 *
 * @author WZLOVE
 * @create 2018-07-25 20:47
 */
public class ClientDemo {

    public static void main(String[] args) throws IOException {
        // 创建Socket对象
        Socket socket = new Socket("localhost",8888);

        // 利用转换流转换成打印流
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);

        // 向服务器写内容
        pw.println("你好,我是客户端");

        // 获取高效字符输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        // 获取服务器发送的消息
        String s = br.readLine();
        System.out.println("服务器说:" + s);

        // 关闭流
        socket.close();
    }

}

package homework.demo5;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 *
 * @author WZLOVE
 * @create 2018-07-25 20:57
 */
public class ServerDemo {

    public static void main(String[] args) throws IOException {
        // 创建服务端网络对象,指定端口号
        ServerSocket ss = new ServerSocket(8888);
        // 获取Socket对象
        Socket accept = ss.accept();
        // 获取高效输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        // 获取输入的信息
        String s = br.readLine();
        System.out.println("客户端说 : " + s);

        // 获取打印流
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(accept.getOutputStream()),true );
        // 向客户端发送消息
        pw.println("你好,我是服务端");
        // 关闭资源
        accept.close();
        ss.close();
    }
}

写个例子,实现客户端向服务器上传图片

package homework.demo7;

import java.io.*;
import java.net.Socket;

/**
 * 网络通信中的客户端
 */
public class Cilent {

    public static void main(String[] args) throws IOException {
        // 创建Socket客户端对象
        Socket socket = new Socket("localhost",8888);
        // 准备文件进行传输
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("yz.jpg"));
        // 使用socket对象获取字节输入流对象
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        // 一边读文件,一边向服务器发送数据
        byte[] arr = new byte[1024 * 5];
        int len;
        while((len = bis.read(arr)) != -1){
            bos.write(arr,0,len);
        }
        // 数据上传完毕,刷新缓存区
        bos.flush();
        // 关闭不用的资源
        bis.close();
        // 关闭输出流套接字,这个步骤是必须的
        socket.shutdownOutput();

        // 读取反馈的数据
        // 使用socket对象获取字节输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine()) != null){
            sb.append(line);
        }
        System.out.println(sb);
        // 关闭资源
        socket.close();
    }

}


package homework.demo7;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务端的对象
        ServerSocket ss = new ServerSocket(8888);
        // 使用服务端对象获取Socket对象
        Socket accept = ss.accept();
        // 准备接受上传的文件并且写入服务器
        // 创建高效字节输出流,用来指向文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.jpg"));
        // 使用socket对象获取文件字节输入流(转化为高效字节输入流)
        BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
        // 边读边写
        byte[] arr = new byte[1024 * 5];
        int len;
        while((len = bis.read(arr)) != -1){
            bos.write(arr,0,len);
            // 进行刷新
            bos.flush();
        }
        // 关闭不使用的资源
        bos.close();
        // 向客户端反馈信息
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(accept.getOutputStream()),true);
        // 写信息
        pw.println("上传成功");
        // 关闭资源
        accept.close();
        ss.close();
    }
}

有关网络的相关知识大家可以去订阅极客时间上的趣谈网络协议,那个讲的很清楚

原文地址:https://www.cnblogs.com/wadmwz/p/9377145.html