主要原理:
客户端Socket需要指明服务端ServerSocket的地址和端口,而服务端只需指明哪个端口来处理数据,要确认是哪个客户端,可通过accept()方法来获取,获取Socket后,主要就是运用IO流来进行数据传输。
由于accept()具有阻塞性,一直等待客户端的连接,如果服务端只用单线程来处理数据,那么每次只能有一个客户端连接并处理数据,这不符合原理,因此我们需要运用多线程,每个线程对应一个客户端,把处理数据的任务过程统一封装到Runnable的run()方法里面去。
具体的代码如下,重点都有注释!!
附C/S解释图:
源码:
客户端:
/**
* 客户端
* ----上传图片到服务端
* @author Smilexs
*
*/
public class PicClient {
public static void main(String[] args) throws Exception {
/**1.建立客户端Socket*/
Socket client = new Socket("localhost",10008);
/**2.创建图片输入字节流*/
// BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\pic1.jpg"));//缓冲字节流可以提高综合效率,并非是缩短时间
FileInputStream fis = new FileInputStream("E:\\pic1.jpg");
/**3.输出到服务端*/
OutputStream os = client.getOutputStream();
byte[] temp = new byte[1024];
int len;
while((len=fis.read(temp))!=-1){
os.write(temp);
}
/*
* 告知服务器已经读完
*/
client.shutdownOutput();
/**4.获取服务端的反馈信息*/
InputStream is = client.getInputStream();
byte[] data = new byte[1024];
len =is.read(data);
System.out.println(new String(data,0,len));
/**5.关闭流和客户端*/
fis.close();
client.close();
}
}
服务器:
/**
* 服务端
* ----接收图片上传
* @author Smilexs
*
*/
public class PicServer {
public static void main(String[] args) throws Exception{
/**1、建立服务器*/
ServerSocket server = new ServerSocket(10008);
while(true){
/**2、一个客户端连接,就创建一个线程*/
Socket curScoket = server.accept();//阻塞式
new Thread(new ClientThread(curScoket)).start();
}
}
}
class ClientThread implements Runnable{
private Socket curSocket;//每个线程对应一个Socket
public ClientThread(Socket curSocket) {
/**1.获取Socket道路*/
this.curSocket = curSocket;
}
@Override
public void run() {
try {
/**2.得到图片输出路径*/
int count = 1;
String picName = curSocket.getInetAddress().getHostAddress();//根据主机名给图片命名
File tempFile= new File("F:\\"+picName+"_"+count+".jpg");
while(tempFile.exists()) {
tempFile= new File("F:\\"+picName+"_"+(count++)+".jpg");//防止覆盖
}
FileOutputStream fos= new FileOutputStream(tempFile);
/**3.根据Socket输入流,读数据,并写*/
InputStream is = curSocket.getInputStream();
byte[] datas = new byte[1024];
while((is.read(datas))!=-1){
fos.write(datas);
}
/**4.发送反馈信息给客户端*/
OutputStream os = curSocket.getOutputStream();
os.write("上传成功".getBytes());
/**5.关闭流,客户端*/
fos.close();
curSocket.close();
} catch (Exception e) {
throw new RuntimeException("");
}
}
}