java多线程文件上传服务器

摘要:
然后为新用户分配一个新线程,以便服务器可以处理多线程。3.8*当服务器和客户端相互传输数据时,将不会发送数据。3当用IO读取文件中的数据,然后将其发送到服务器13*时,服务器上的接收器14*(sin.read())将不会接收到发送完成的消息。

 描述:

(1)jdk自带线程池见 JDK自带线程池配置

(2)此上传文件服务器中上传文件的后缀名通过第一段缓冲字符流传递,此缓冲字符流大小为1024,在文件接收端以1024接收、处理。

1、服务器代码如下(使用jdk自带线程池):

 1 /**
 2  * 服务器处理多线程问题
 3  * 
 4  * 1.因为服务器是要很多人访问的,因此里面一定要用多线程来处理,不然只能一个人一个人的访问,那还叫Y啥服务器
 5  * 
 6  * 2,拿上面这个文件上传的例子来说,它将每个连接它的用户封装到线程里面去,把用户要执行的操作定义到 run 方法里面
 7  * 一个用户拿一个线程,拿到线程的就自己去执行,如果有其它用户来的时候,再给新来的用户分配一个新的线程 这样就完成了服务器处理多线程的问题 3.
 8  * 在服务器与客户端互传数据时,我们要特别注意的是,防止两个程序造成 死等的状态,一般原因有以下:
 9  * 
10  * 1. 客户端向数据端发送数据时,当发送的是字符时,第次以一行来发送,而服务端在读取的时候,也是以 一行来读取,readLine()
11  * 而发送的时候往往只是发送换行以行的内容,而不能发换行也发送过去, 那么服务端在读取的时候就不读取不到换行 ,那么 readLine() 就不会停止 2.
12  * 客户端发送数据时,如果处理的是用 字符流 或是缓冲流的话,一定要记得刷新流,不然的话,数据就会发不出来 3 在用IO 读取文件里面的数据然后发送到服务端
13  * 时,当家读取文件 while(in.read()) 读取文件结束时,而在 服务端的接收程序
14  * while(sin.read())不会接到一个发送完毕的提示,所以会一直等待下去,所以我们在处理这
15  * 个问题的时候,还要将其发送一个文件读取结束的标志,告诉接收端文件已经读取完结,不要再等待了 而socket 里面给我们封装了 shutdownInput
16  * shutdownOutput 两个操作,此可以关闭 流,两样也可以起到告诉 接收方文件传送完毕的效果
17  * 
18  * 
19  * 
20  * */
21 public class Server {
22     
23     private static Logger logger = LoggerFactory.getLogger(Server.class);
24     private static final Integer PORT = 2222;
25     
26 
27     public static void main(String args[]) throws Exception {
28 
29         ServerSocket server = new ServerSocket(PORT);
30         
31         logger.info("服务器启动:::端口号为:{}",PORT);
32         ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 300, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(3),
33                 new ThreadPoolExecutor.CallerRunsPolicy());
34         
35         while (true) {
36             
37             Socket client = server.accept();
38             executor.execute(new UploadThread(client));
39 //            new Thread(new UploadThread(client)).start();
40         }
41 
42     }
43 }

2、上传文件代码如下:

package cn.iautos.manager.test.load;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;

public class Upload {
	
	public static void main(String args[]) throws Exception {
		
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			public void run() {
				try {
					System.out.println("--------开始上传文件-------");
					loadMethod();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}, 0, 500);
	}
	
	public static void loadMethod() throws Exception{

		String name = "E:\qqq.jpg";
		Socket client = new Socket("127.0.0.1", 2222);
		File file = new File(name);
		
		String imgSuffix = ImgUtils.getImgSuffix(name);
		
		BufferedInputStream fin = new BufferedInputStream(new FileInputStream(
				file)); // 文件读取流
		PrintStream sout = new PrintStream(client.getOutputStream(), true); // 得到socket流
		/**
		 * 添加后缀名
		 */
		byte[] b = new byte[1024];
			byte[] bb = (imgSuffix+"
").getBytes();
			for(int j = 0;j<bb.length;j++){
				b[j] = bb[j];
			}
		sout.write(b,0,b.length);
		
		int len = 0;
		while ((len = fin.read(b)) != -1) {
			sout.write(b, 0, len);
			System.out.println(len + "...发送中");
		}
		client.shutdownOutput();
		BufferedInputStream sin = new BufferedInputStream(client
				.getInputStream());
		len = sin.read(b);
		System.out.println(len);
		System.out.println(new String(b, 0, len));
		sin.close();
		sout.close();
		fin.close();

	
		
	}
}

3、接收文件代码如下:

package cn.iautos.manager.test.load;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class UploadThread implements Runnable // 将上传封装到线程里
{
    private Socket client;

    public UploadThread(Socket s) {
        this.client = s;
    }

    public void run() {
//        String ip = client.getInetAddress().getHostAddress(); // 得到 IP地址
        try {
            BufferedInputStream sin = new BufferedInputStream(client.getInputStream()); // Socket 读取流
            byte b[] = new byte[1024];
            int l = sin.read(b);
            String line = new String(b, 0, l).split("
")[0];
            System.out.println("--------文件后缀为------"+line);
            
            File file = new File("E:\loadServer\" + ImgUtils.getImgName()
                    + line);
            BufferedOutputStream fout = new BufferedOutputStream(
                    new FileOutputStream(file)); // 文件输出流
            
            int len = 0;
            // 开始从网络中读取数据
            while (true) {
                len = sin.read(b);
                if(len != -1){
                    fout.write(b, 0, len);
                }else{
                    break;
                }
//                System.out.println("--------------"+new String(buf,0,len));
            }
            PrintStream sout = new PrintStream(client.getOutputStream());
            sout.write("发送成功".getBytes());
            // sout.flush(); //虽然是字节流,但其用的是BufferedOutputStream
            fout.close();
            sin.close();
            sout.close();
        } catch (Exception ex) {
            System.out.println();
            ex.printStackTrace();

        }

    }
}

免责声明:文章转载自《java多线程文件上传服务器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇vite支持optionalChaining可选链判断运算符和nullishCoalescingOperator[学习笔记]关于CUDA与OPENCL下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

NTFS隐写

------------恢复内容开始------------ 总结下以前做题遇到的有趣的知识点, Buuctf里的杂项漂流的马里奥,中NTFS隐写到NTFS在渗透过程的妙用。 NTFS交换数据流(Alternate DataStreams,简称ADS)是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流。通俗的理解,就是其它文件...

Adobe photoshop CS6 + 破解补丁

软件位置:  链接:https://pan.baidu.com/s/1KeKRS0yIMfeEbOJQ-ilo0g 破解流程 首先断开网络连接 (如果不断网安装过程中会要求登陆)打开Photoshop CS6文件夹里的Adobe CS6文件夹双击set-up.exe 进行安装询问[安装]或[试用]时 选择试用用试用方式不需要输入序列号 安装完成后打开一次...

Nwjs简单配置

1.创建一个工程,配置一个  package.json 文件 { "name": "application-name", "version": "0.0.1", "main":"index.html" }   上面的"main"对应自己创建的html文件,作为NWjs的入口 2.配置工程的环境:(1)下载  nwjs-sdk-v0.18.6-...

win7 64位 安装 VS2010 SP1 失败的解决方法

1. 系统环境:Windows Server 2008 R2(与Win7 x64系统相似),VS2010及常用办公、编程工具等软件2. 问题症状:无论是通过在线安装包还是ISO安装包安装,多次安装,都在安装过程中回滚,最终安装失败。3. 产生原因:系统安装整一年,常年使用,系统自动补丁等操作,使得原系统盘C盘40G空间告急,于是动手删除了部分C:Windo...

统计一个版本代码变化行数

项目总结时,我们常常需要统计代码行数,来查看每个项目开发者的代码总量,提交次数和变更文件数。 这里介绍一下statsvn工具统计代码行数的方法。   1、安装tortoise svn 下载tortoise svn,下载地址:https://tortoisesvn.net/downloads.html,附件给出了64位的版本。 点击运行,按照提示安装完成。...

jwt token

jwt使用配置: settings文件中添加: REST_FRAMEWORK = { # 异常处理 自定义的异常处理类 'EXCEPTION_HANDLER': 'drf_meiduo.utils.exceptions.exception_handler', 'DEFAULT_AUTHENTICATION_CLASSES': (...