服务端处理客户端的请求,对于Socket采用TCP连接的手段来说,由于一个SocketServer只对应和一个Socket通信。所以,为了有效的控制服务端的服务质量,采取线程池的策略。集体说来就是开启若干个SocketServer来对预想连接到服务器的客户端们进行处理,若是同一时间有很多客户端涌入,线程池中的ServerSocket都不够用了都被占用了,则多余的那些客户端就先等待,等有的ServerSocket执行完之后再来和他们通信处理。具体的最简单的线程池实现如下代码所示(每个ServerSocket实现了接受文件的任务,而假想很多客户端涌入要求向服务端传输文件):
package com.wjy.threadpool; import java.io.BufferedInputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import com.wjy.receivefile.ReceiveFile; public class ThreadPool { private int port; private int poolSize=0; private ServerSocket server; public ThreadPool(int port, int poolSize) { super(); this.port = port; this.poolSize = poolSize; } private void startServer(){ try { server=new ServerSocket(port); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private int fileNum(){ int result=(int)(Math.random()*10); return result; } public void startThreadPool(){ startServer(); for(int i=0;i<poolSize;i++){ //其实我们可以分析一下,若没有这个for循环,就是说线程池中只有一个线程进行处理。所以没有这个线程也是可以的。 Thread thread=new Thread(){ public void run(){ while(true){ try { Socket client=server.accept(); int num=fileNum(); System.out.println(num); BufferedInputStream inputStream=new BufferedInputStream(client.getInputStream()); ReceiveFile receiveFile=new ReceiveFile(inputStream, "E://receive/"+num+".txt"); Thread.sleep(15000); receiveFile.receiveFile(); } catch (Exception e) { e.printStackTrace(); } } } }; thread.start(); } } }
开启服务器的代码:
package com.wjy.test; import com.wjy.threadpool.ThreadPool; public class MainTestThreadPool { public static void main(String args[]){ ThreadPool threadPool=new ThreadPool(8765,2); threadPool.startThreadPool(); } }
接受文件的类的代码:
package com.wjy.receivefile; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class ReceiveFile { private int buffSize=1024; private BufferedInputStream conveyInputStream; private BufferedOutputStream fileOutputStream; public void setBuffSize(int buffSize) { this.buffSize = buffSize; } public ReceiveFile(BufferedInputStream conveyInputStream, String filePath) { super(); this.conveyInputStream = conveyInputStream; try { this.fileOutputStream=new BufferedOutputStream(new FileOutputStream(new File(filePath))); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void receiveFile(){ byte buff[]=new byte[buffSize]; try { while((conveyInputStream.read(buff, 1, buffSize-1))!=-1){ fileOutputStream.write(buff, 1, buffSize-1); } conveyInputStream.close(); fileOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
现在模拟很多客户端同时请求传输文件的请求:
先看看传输文件类的代码:
package com.wjy.conveyfile; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class ConveyFile { private int buffSize=1024; private BufferedInputStream fileInputStream; private BufferedOutputStream conveyOutputStream; public void setBuffSize(int buffSize) { this.buffSize = buffSize; } public ConveyFile(BufferedOutputStream conveyOutputStream, String filePath) { super(); this.conveyOutputStream = conveyOutputStream; try { this.fileInputStream=new BufferedInputStream(new FileInputStream(new File(filePath))); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void conveyFile(){ int index; byte buff[]=new byte[buffSize]; try { while((index=(fileInputStream.read(buff, 1, buffSize-1)))!=-1){ conveyOutputStream.write(buff, 1, index); conveyOutputStream.flush(); } fileInputStream.close(); conveyOutputStream.close(); //当这里关闭之后,接收端会通过read返回-1。表明文件传输完毕。 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
以下为客户端代码,写5个同时运行:
package com.wjy.test; import java.io.BufferedOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Date; import com.wjy.conveyfile.ConveyFile; public class ThreadPoolTestClient1 { public static void main(String args[]){ for(int i=0;i<5;i++){ try { Socket client=new Socket("10.13.30.22",8765); int num=(int)(Math.random()*10); System.out.println(new Date()+" 1: "+num); //将代码复制4遍,这里的1分别改为2,3,4,5。同时运行着五个客户端会产生25个客户端连接请求。 BufferedOutputStream outputStream=new BufferedOutputStream(client.getOutputStream()); ConveyFile conveyFile=new ConveyFile(outputStream, "E://send/"+num+".txt"); Thread.sleep(3000); conveyFile.conveyFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }