/** 前两个视频客户端上传图片给服务端的若干问题:* * 1.服务端开启,此时张三连进来,获取张三Socket对象,张三上传完毕,关闭张三Socket,ss.close(),服务端也关闭,所以* 此时其余人无法上传文件。* * 2.为克服问题1,有如下程序:* ServerSocket ss = new ServerSocket(20000);* while(true){* Socket s = ss.accept();* 流对象的不断读写操作......* s.close();* }* 此时问题1解决,但是新问题出现,由于此时只有主线程这一个线程在工作,所以客户端1进入while循环,获取客户端1的Socket对象,* 开始读写操作,此时客户端2连进来了,那么获取不到客户端2的Socket对象,因为主线程在操作客户端1的读写,所以还是有问题。* →上传图片需要排队。(如别人登录新浪,你登录不了,同一时间只一个登录新浪)*//*** 上述问题可用多线程并发解决,思考发现while循环中的“流对象的不断读写操作......”不管哪个客户端连进来都要做这步,* 而Socket s = ss.accept()可以用一个线程单独封装操作,即客户端1用线程1,客户端2用线程2……* * 程序运行,客户端1连进来,主线程立马安排线程1给客户端1(下面由线程1带领客户端1完成读写等操作),此时主线程立马回到* 开始等待客户端2连接,客户端2一连接,主线程立马安排线程2给客户端2(下面由线程2带领客户端2完成读写操作),此时主线程* 立马回到开始等待客户端3连接……如此往复,这就是【服务器原理:客户端并发访问】,程序如下:* ServerSocket ss = new ServerSocket(20000);* while(true){* Socket s = ss.accept();主线程在这等着,有一个客户端连接* new Thread(new Task(s)).start();主线程就安排一个线程【将连接进来的客户端封装到一个线程中】* 流对象的不断读写操作......* s.close();* }*/package test;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class TCPThreadTest {public static void main(String[] args) throws IOException {//将UploadServerOfPhoto代码修改ServerSocket ss = new ServerSocket(10006);while(true){Socket s = ss.accept();new Thread(new UploadTask(s)).start();}//ss.close();这里无需关闭,因为while无限循环}}
======================分割线====================================
package test;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;public class UploadTask implements Runnable {private Socket s;private int count = 0;public UploadTask(Socket s) {this.s = s;}@Overridepublic void run() {// 这里写的代码是每个客户端连接到服务端均要做的事情String ip = s.getInetAddress().getHostAddress();System.out.println(ip + "......connected");try {InputStream in = s.getInputStream();File dir = new File("c:\\pic");if (!dir.exists())dir.mkdirs();File file = new File(dir, ip + ".bmp");/** 有可能出现同一个客户端上传不止一个文件的情况,为了防止后一个文件将前一个覆盖,这里给文件名加上编号。(这就是* 为什么迅雷下载同一个文件,第一个若叫xxx.bmp,第二个叫xxx(1).bmp的原因)*/if(file.exists())file = new File(dir,ip+"("+(++count)+")"+".bmp");FileOutputStream fos = new FileOutputStream(file);byte[] bufIn = new byte[1024];int lenIn = 0;while ((lenIn = in.read(bufIn)) != -1) {fos.write(bufIn, 0, lenIn);}OutputStream out = s.getOutputStream();out.write("上传成功......".getBytes());fos.close();s.close();} catch (IOException e) {}}}