JAVA基础再回首(二十九)——TCP传输、上传文件、上传图片、多并发上传

原创 2016年10月02日 19:30:14

JAVA基础再回首(二十九)——TCP传输、上传文件、上传图片、多并发上传

版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917

上篇我们学完了UDP传输,并完成了UDP传输数据聊天,这篇我们来学习TCP传输

TCP传输

TCP传输是怎样建立的呢?


  • Socket和ServerSocket
  • 建立客户端和服务器端
  • 建立连接后,通过Socket中的IO流进行数据的传输
  • 关闭socket

TCP传输客户端与服务器端同样是两个独立的应用程序。
我们就来写一个TCP输出数据的程序。

TCP传输-客户端

/*
 * TCP协议发送数据:
 * A:创建发送端的Socket对象
 *      这一步如果成功,就说明连接已经建立成功了。
 * B:获取输出流,写数据
 * C:释放资源
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建发送端的Socket对象
        Socket s = new Socket("192.168.2.102", 8888);

        // 获取输出流,写数据
        OutputStream os = s.getOutputStream();
        os.write("TCP来了".getBytes());

        // 释放资源
        s.close();
    }
}

TCP传输-服务器

/*
 * TCP协议接收数据:
 * A:创建接收端的Socket对象
 * B:监听客户端连接。返回一个对应的Socket对象
 * C:获取输入流,读取数据显示在控制台
 * D:释放资源
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建接收端的Socket对象
        ServerSocket ss = new ServerSocket(8888);

        // 监听客户端连接。返回一个对应的Socket对象
        Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。

        // 获取输入流,读取数据显示在控制台
        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];
        int len = is.read(bys); // 阻塞式方法
        String str = new String(bys, 0, len);

        String ip = s.getInetAddress().getHostAddress();

        System.out.println(ip + "---" + str);

        // 释放资源
        s.close();
        // ss.close(); //服务器一般不应该关闭
    }
}

这样我们九建立了TCP协议传输数据的客户端和服务器,运行程序,服务器会收到客户端发来的数据,但是这样的代码,当服务器端收到客户端的数据时,客户端并不知道,所以,我们就要给客户端一个反馈了。

/*
 * 服务器端
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建服务器Socket对象
        ServerSocket ss = new ServerSocket(11111);

        // 监听客户端的连接
        Socket s = ss.accept(); // 阻塞

        // 获取输入流
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys); // 阻塞
        String server = new String(bys, 0, len);
        System.out.println("server:" + server);

        // 获取输出流
        OutputStream os = s.getOutputStream();
        os.write("数据已经收到".getBytes());

        // 释放资源
        s.close();
        // ss.close();
    }
}

/*
 * 客户端
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建客户端Socket对象
        Socket s = new Socket("192.168.2.102",11111);

        // 获取输出流
        OutputStream os = s.getOutputStream();
        os.write("国庆节快乐!".getBytes());

        // 获取输入流
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);// 阻塞
        String client = new String(bys, 0, len);
        System.out.println("client:" + client);

        // 释放资源
        s.close();
    }
}

这样,当客户端与服务器建立连接后,服务器成功收到客户端发来的消息(server:国庆节快乐!),客户端会就会有一个反馈(client:数据已经收到)

上传文件

我们来完成通过TCP协议从客户端上传一个文件到服务器,并给出客户端反馈文件上传成功

/*
 * 上传文件客户端
 */
public class UploadClient {
    public static void main(String[] args) throws IOException {
        // 创建客户端Socket对象
        Socket s = new Socket("192.168.2.102", 12345);

        // 封装文本文件
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        // 封装通道内流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                s.getOutputStream()));

        String line = null;
        while ((line = br.readLine()) != null) { // 阻塞
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了
        s.shutdownOutput();

        // 接收反馈
        BufferedReader brClient = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        String client = brClient.readLine(); // 阻塞
        System.out.println(client);

        // 释放资源
        br.close();
        s.close();
    }
}

/*
 * 上传文件接收端(服务器)
 */
public class UploadServer {
    public static void main(String[] args) throws IOException {
        // 创建服务器端的Socket对象
        ServerSocket ss = new ServerSocket(12345);

        // 监听客户端连接
        Socket s = ss.accept();// 阻塞

        // 封装通道内的流
        BufferedReader br = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        // 封装文本文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

        String line = null;
        while ((line = br.readLine()) != null) { // 阻塞
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        // 给出反馈
        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(
                s.getOutputStream()));
        bwServer.write("文件上传成功");
        bwServer.newLine();
        bwServer.flush();

        // 释放资源
        bw.close();
        s.close();
    }
}

这是上传文件并给出反馈的例子,我们再来看上传图片并给出反馈的例子怎么写

上传图片

上传图片我们就要考虑不能用字符流了,要用字节流。

/*
 * 上传图片客户端
 */
public class UploadClient {
    public static void main(String[] args) throws IOException {
        // 创建客户端Socket对象
        Socket s = new Socket("192.168.2.102", 96320);

        // 封装图片文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg"));
        // 封装通道内的流
        BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
            bos.flush();
        }

        s.shutdownOutput();

        // 读取反馈
        InputStream is = s.getInputStream();
        byte[] bys2 = new byte[1024];
        int len2 = is.read(bys2);
        String client = new String(bys2, 0, len2);
        System.out.println(client);

        // 释放资源
        bis.close();
        s.close();
    }
}

/*
 * 上传图片接收端-服务器
 */
public class UploadServer {
    public static void main(String[] args) throws IOException {
        // 创建服务器Socket对象
        ServerSocket ss = new ServerSocket(96320);

        // 监听客户端连接
        Socket s = ss.accept();

        // 封装通道内流
        BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
        // 封装图片文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.jpg"));

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
            bos.flush();
        }

        // 给一个反馈
        OutputStream os = s.getOutputStream();
        os.write("图片上传成功".getBytes());

        bos.close();
        s.close();
    }
}

运行程序,我们将客户端a.jpg的图片上传到服务器后,服务器收到后会给我们返回图片上传成功

多并发上传

在我们平时遇到的情况肯定不是一个客户端对应一个服务器,肯定是多个客户端对应一个服务器,那么就存在了多并发上传,再大型项目中也要考虑服务器的负荷问题,那么我们就来用代码实现一下当多个用户上传文件到服务器时,我们应该怎样做?

如果我们还按照上面上传文件的思路,去进行多并发上传,当一个客户端A建立连接之后,被服务端获取到,服务端就在执行代码了,这个时候如果客户端B建立连接只有等待客户端A操作完成后它才能开始执行,所以为了让多个客户端同时连接到服务器上传代码,我们就要运用多线程技术,把每个客户端和服务器之间的连接封装到一个线程中去,这样就可以同时处理多个客户端请求
>

/*
 * 服务器端
 */
public class UploadServer {
    public static void main(String[] args) throws IOException {
        // 创建服务器Socket对象
        ServerSocket ss = new ServerSocket(11111);

        while (true) {
            Socket s = ss.accept();
            new Thread(new UserThread(s)).start();
        }
    }
}

/*
 * 并发的线程
 */
public class UserThread implements Runnable {
    private Socket s;

    public UserThread(Socket s) {
        this.s = s;
    }

    @Override
    public void run() {
        try {
            // 封装通道内的流
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    s.getInputStream()));

            // 为了防止名称冲突,每次命名为随机的
            String newName = System.currentTimeMillis() + ".java";
            BufferedWriter bw = new BufferedWriter(new FileWriter(newName));

            String line = null;
            while ((line = br.readLine()) != null) { // 阻塞
                bw.write(line);
                bw.newLine();
                bw.flush();
            }

            // 给出反馈
            BufferedWriter bwServer = new BufferedWriter(
                    new OutputStreamWriter(s.getOutputStream()));
            bwServer.write("文件上传成功");
            bwServer.newLine();
            bwServer.flush();

            // 释放资源
            bw.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

这样就完成了多用户上传文件到客户端了。

学到这里,我们的java基础也回首的差不多了,可能有个别的知识点,没有回首到,大家可以上网查阅资料自己学习下,但是大部分知识点我还是再回首了一遍了,收获很多,感谢大家对我的支持,我会再写一篇java基础的完结篇给大家。希望大家在编程的道路上走的更远,取得更多的辉煌。谢谢大家。

欢迎有兴趣的同学加我朋友的QQ群:点击直接加群555974449 请备注:java基础再回首我们一起来玩吧。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m366917/article/details/52724684

百度webuploader上传文件组件案例分析和使用-web网站开发3

-
  • 1970年01月01日 08:00

Java高并发读写文件

在实际的项目中我们经常会与遇到操作文件的情况,这是很常见的,但是我们在实际中用传统的I/O操作不能满足我们项目的需要并且对文件的写特别慢,操作比较麻烦。那么我们怎么样实现呢?最近在项目中我们遇到了高并...
  • wsxxm_h
  • wsxxm_h
  • 2016-11-10 16:30:24
  • 5488

java之多线程解决TCP服务端并发上传

示例代码: /** * TCP服务端利用多线程解决并发上传 * @author 小苏 * */ public class TCP_Upload_Concurrent { public ...
  • w465560907
  • w465560907
  • 2014-12-19 21:16:56
  • 539

java socket多线程文件上传下载实例项目

  • 2013年10月12日 11:36
  • 2.73MB
  • 下载

Java高性能文件上传及下载

  • 2012年08月01日 10:14
  • 337KB
  • 下载

分布式高并发上传设计思路图

  • 2017年10月27日 14:25
  • 17KB
  • 下载

大文件分块上传第三弹(分块并发上传)

继上次大文件分块上传原理第二弹见:http://blog.csdn.net/haohao123nana/article/details/54692669,有童靴说前端分片递归上传效率不高,我试了试前端...
  • haohao123nana
  • haohao123nana
  • 2017-08-17 18:23:22
  • 617

图片上传-并发性知识

我们访问一个传统的系统,上传图片时图片可能保存在Webapp 下的某一个文件夹里面,当系统访问量增加过多,发生了严重的并发性,我们可以为这个系统多添加一个服务器,做Tomcat集群。 此时不做负...
  • qq_33218964
  • qq_33218964
  • 2017-12-16 15:56:40
  • 158

如何实现支持大文件的高性能HTTP文件上传服务器

简单介绍了如何实现一个高性能的HTTP文件上传服务器,用于支持2GB以上大文件传输的文件服务求,支持1000个并发上传请求,支持HTML5方式、Flash插件SWFUpload文件上传。...
  • ababab12345
  • ababab12345
  • 2017-08-12 21:48:12
  • 4384

JAVA之旅(三十三)——TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录

JAVA之旅(三十三)——TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录 我们继续网络编程 一.TCP 说完UDP,我们就来说下我们应该重点掌握的TCP了TCP传输 ...
  • qq_26787115
  • qq_26787115
  • 2016-08-20 10:33:26
  • 3691
收藏助手
不良信息举报
您举报文章:JAVA基础再回首(二十九)——TCP传输、上传文件、上传图片、多并发上传
举报原因:
原因补充:

(最多只允许输入30个字)