[javaSE] 网络编程TCP-并发上传图片

客户端:

1.服务端点

2.读取客户端已有的图片数据

3.通过socket输出流将数据发给服务端

4.读取服务端反馈信息

5.关闭

 

获取Socket对象,new出来,构造参数:String的服务端ipint的端口号

调用Socket对象getOutputStream()方法,得到OutputStream输出流对象

获取FileInputStream对象new出来,构造参数:String的文件路径

while循环调用,条件FileInputStream对象的read()方法,读取到字节数组中

循环中,调用OutputStream输出流对象的write()方法,写入数据,参数:byte[]0len

调用Socket对象的shutDownOutput()方法,通知服务端写入完成

 

调用Socket对象的getInputStream()方法,得到InputStream输入流对象

调用InputStream输入流对象的read()方法,读取,并打印

 

调用FileInputStream对象的close()方法

调用Socket对象的close()方法

 

服务端:

正常读取

 

解决并发

上面的例子,一次只能有一个客户端服务,解决并发上传的问题,使用多线程处理每个来访的客户

定义一个类PicThread,实现Runnable接口

定义构造函数,传递进来Socket对象

实现run()方法,在try-catch中捕获异常,正常读取Socket对象的流

 

 

解决文件覆盖

文件的名称采用ip+(数字),例如:192.168.1.100(2).jpg

获取ip 方法,socket.getInetAddress().getHostAddress()

第一次进入,文件名192.168.1.100.jpg

第二次进入,判读文件已存在,文件名变成192.168.1.100(1).jpg

 

主函数传值形式并判断

判断有一个参数 arg.length==1

判断是文件,并且存在  File对象的exists()方法和isFile()方法

判断文件后缀,File对象的getName().endsWith(“.jpg”)方法

判断文件大小,File对象的length()方法

import java.io.File;
 java.io.FileInputStream;
 java.io.FileOutputStream;
 java.io.IOException;
 java.io.InputStream;
 java.io.OutputStream;
 java.net.ServerSocket;
 java.net.Socket;
 java.net.UnknownHostException;

class UploadPicClient {

    /**
     * @param args
     * @throws IOException
     *  UnknownHostException
     */
    public static void main(String[] args) throws Exception {
        //判断参数
        if(args.length!=1){
            System.out.println("请选择一个文件");
            return;
        }
        File file=new File(args[0]);
        if(!file.exists()||!file.isFile()){
            System.out.println("请选择一个存在的文件";
        }
        if(!file.getName().endsWith(".png")||file.length()>(1024*1024)){
            System.out.println("请选择小于1M的png文件";
        }
        Socket socket = new Socket("127.0.0.1",10001);
        OutputStream out = socket.getOutputStream();
         输出
        FileInputStream fileInputStream = new FileInputStream("E:/11.png");
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fileInputStream.read(b)) != -1) {
            out.write(b,0,len);
        }
         通知服务端
        socket.shutdownOutput();

         接收反馈
        InputStream inputStream = socket.getInputStream();
        byte[] res = ];
        len = inputStream.read(res);
        System.out.println(new String(res,0
 * 多线程上传
 * @author taoshihan
 *
 */
class UploadPicServerThread implements Runnable {
    private Socket socket;

    public UploadPicServerThread(Socket s) {
        this.socket = s;
    }

    @Override
    void run() {
         读取
        InputStream is;
        try {
            is = socket.getInputStream();

            ];
            ;
             解决文件覆盖
            String ip = socket.getInetAddress().getHostAddress();
            int fileNum = 1;
            File file = new File(ip + ".png"while (file.exists()) {
                file = new File(ip + "(" + (fileNum++) + ").png");
            }
            FileOutputStream fos = new FileOutputStream(file);
            while ((len = is.read(res)) != -1) {
                fos.write(res,len);
            }

             反馈
            OutputStream os = socket.getOutputStream();
            os.write("上传成功!".getBytes());
            is.close();
            os.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

 服务端
 UploadPicServer {

     Exception
      Exception {
        ServerSocket serverSocket = new ServerSocket(10001);

        while (true) {
            Socket socket = serverSocket.accept();
            new Thread( UploadPicServerThread(socket)).start();
        }
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


@ 注解能被用来为程序元素( 类、 方法、 成员变量等) 设置元数据。 值得指出的是, 注解不影响程序代码的执行, 无论增加、 删除注解, 代码都始终如一地执行。 如果希望让程序中的注解在运行时起一定
@ 1、线性表的概念 线性表是最常见也是最简单的一种数据结构。简言之, 线性表是n个数据元素的有限序列。 其一般描述为: A={a1,a2,……an) 一个数据元素通常包含多个数据项, 此时每个数据元
简介 ArrayList是开发中使用比较多的集合,它不是线程安全的,CopyOnWriteArrayList就是线程安全版本的ArrayList。CopyOnWriteArrayList同样是通过数组
在 Java String类源码阅读笔记 里学习了String类的源码,StringBuilder、StringBuffer是经常拿来和String类做对比的两个类,可谓是“爱恨纠缠” ,这里我们继续
话不多说,先上图。 1、基本概念 欲说线程,必先说进程。 进程:进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 线程:线程是进程的一个执行路径,一个进程中至少有一个线程,进
@ 网络基础 计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一种网络协议。 那什么是互联网呢?互联网是网络的网络(internet
JVM是面试中必问的部分,本文通过思维导图以面向面试的角度整理JVM中不可不知的知识。 先上图: 1、JVM基本概念 1.1、JVM是什么 JVM 的全称是 「Java Virtual Machine
@ 本文基于jdk1.8 HashMap采用 key/value 存储结构,每个key对应唯一的value。 在jdk1.7之前,HashMap 的内部存储结构是数组+链表。 在jdk1.8中 Has
@ Eclipse是很多Java开发者的第一个开发工具,尽管开源的Eclipse在一后起之秀的对比下,显得有些颓势,但是,Eclipse有着丰富的插件支持。选择合适的插件,Eclipse表示:老夫也能
@ 准备 LinkedList是基于双向链表数据结构实现的Java集合(jdk1.8以前基于双向循环链表),在阅读源码之前,有必要简单了解一下链表。 先了解一下链表的概念:链表是由一系列非连续的节点组
@ 写博客哪有刷逼乎有意思 1 写博客哪有刷逼乎有意思 2 写博客哪有刷逼乎有意思 3 类的加载、 连接和初始化 系统可能在第一次使用某个类时加载该类, 也可能采用预加载机制来加载某个类。 JVM 和
树结构是一类重要的非线性数据结构。直观来看,树是以分支关系定义的层次结构。树结构在客观世界广泛存在,如人类社会的族谱和各种社会组织机构都可用树来形象表示。 树在计算机领域中也得到广泛应用,尤以二叉树最
@ 本文基于jdk1.8 String类可谓是我们开发中使用最多的一个类了。对于它的了解,仅仅限于API的了解是不够的,必须对它的源码进行一定的学习。 一、前置 String类是Java中非常特别的一
随便打开一个招聘网站,看看对高级Java工程师的技能要求。 抛开其它的经验能力等等,单纯从技术,或者说知识上来讲,可以发现一些共通的地方。 Java基础 计算机基础 数据库,SQL/NoSQL 常用开
@ JDBC指Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。 1、JDBC典型用法 1.1、JDBC 4.2 常用接口和类简介
简介 ArrayList是基于数组实现的一种列表。 ArrayList继承体系如下: 图一:ArrayList继承体系 ArrayList实现了List, RandomAccess, Cloneabl
@ Java 的 IO 通过 java.io 包下的类和接口来支持, 在 java.io 包下主要包括输入、 输出两种 10 流, 每种输入、 输出流又可分为字节流和字符流两大类。 其中字节流以字节为
@ 使用断言 断言(Assertion)是一种调试程序的方式。在Java中,使用assert关键字来实现断言。 断言的概念 假设确信某个属性符合要求, 并且代码的执行依赖于这个属性。例如, 需要计算:
@ Java 程序在不同操作系统上运行时,可能需要取得平台相关的属性,或者调用平台命令来完成特定功能。 Java 提供了 System 类和 Runtime 类来与程序的运行平台进行交互。 Syste
@ Java 提供了一个操作 Set 、 List 和 Map等集合的类:Collections , 该工具类里提供了大量方法对集合元素进行排序、 查询和修改等操作,还提供了将集合对象设置为不可变、对