Java基础21-TCP

来源:互联网 发布:sql默认实例 编辑:程序博客网 时间:2024/06/06 05:27

一.TCP传输数据
 1.TCP和UDP的区别
  UDP是无连接的, 指定地址和端口后就可以发送, 数据不安全, 速度快.
  TCP是面向连接的, 区分客户端和服务端, 数据安全.


 2.上传文件
 服务端:
  0.创建upload文件夹
  1.创建ServerSocket, 在循环中等待和客户端请求, 每收到一个请求, 开启一条新线程.
  5.获取输入输出流
  7.接收文件名, 接收文件大小, 判断upload文件夹中该文件是否存在
  8.如果存在, 发送提示消息到客户端, 服务端return
  9.如果不存在, 发送提示消息到客户端
  13.接收客户端传输数据, 从Socket中读取数据, 写出到文件中
  
 客户端:
  2.创建BufferedReader, 从键盘接收一个文件路径, 验证是否合法
  3.创建Socket, 连接服务端
  4.获取输入输出流
  6.将文件名发送到服务端, 将文件大小发送到服务端
  10.接收提示消息, 判断是否存在
  11.如果存在, 在客户端打印提示, return
  12.如果不存在, 开始上传, 从文件中读取, 写出到Socket中

 
二.telnet使用
 1.设置回显
  telnet - 回车
  set localecho - 回车
  quit - 回车
 2.使用
  telnet 地址 端口 - 回车
  ctrl + ] - 回车
  输入数据
注意:
  telnet是逐个字符发送的, 输入一个字符就发送一个字符

 

三.多线程文件上传及断点续传

源代码:

   客户端Client

package cn.base24.tcp;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintStream;import java.net.Socket;import java.net.UnknownHostException;/* * 版本v2.0:(add:断点续传) * 使用TCP传输文件的客户端: */public class FileUploadClient2 {public static void main(String[] args) {FileInputStream fi = null;Socket socket = null;try {socket = new Socket("192.168.1.106", 6789);BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedReader brReadKey = new BufferedReader(new InputStreamReader(System.in));PrintStream ps = new PrintStream(socket.getOutputStream());File file = getFile(brReadKey);//验证输入的路径ps.println(file.getName());//传输文件名和文件大小,以确定是否需要断点续传ps.println(file.length());String line = br.readLine();//接收服务端返回的数据long lengthDest = 0;long skipNum = 0;//记录需要跳过的字节数if("文件已存在.请不要重复上传!".equals(line)) {//若文件完整且重复,返回是-文件已存在.请不要重复上传!System.out.println("文件已存在.请不要重复上传!");return;} else {lengthDest = Integer.parseInt(line);//将返回的数据,转换if(lengthDest != file.length()) {//比较大小是否一样,不一样则将服务器端的大小作为需要跳过的字节数skipNum = lengthDest;//若是0,则表示服务器端没有该文件,则跳过的数目就是0}}System.out.println( skipNum ==0 ? "开始上传..." : "断点续传...");fi = new FileInputStream(file.toString());OutputStream out = socket.getOutputStream();int len = 0;byte[] b = new byte[1024];fi.skip(skipNum);//跳过字节数while((len= fi.read(b))!=-1) {out.write(b, 0, len);}System.out.println(skipNum ==0 ? "上传成功!" : "断点续传结束!");} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if(fi != null)fi.close();} catch (IOException e) {e.printStackTrace();} finally {try {if(socket != null)socket.close();} catch (IOException e) {e.printStackTrace();}}}}/* * 从键盘接收源文件的路径,保证输入的文件路径正确 */private static File getFile(BufferedReader brReadKey) throws IOException {String line =null;File file = null;System.out.println("请输入需要上传的文件路径:");while(true) {line = brReadKey.readLine();file = new File(line);if(!file.exists()) {System.out.println("文件不存在!请输入需要上传的文件路径:");} else if(file.isDirectory()) {System.out.println("暂不支持上传文件夹功能!请输入需要上传的文件路径:");} else{break;}}return file;}}

 

服务端Server:

package cn.base24.tcp;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.ServerSocket;import java.net.Socket;import java.text.SimpleDateFormat;import java.util.Date;/* * 版本v2.0:(add:断点续传) ---<注意: 若是断点续传,则应该是追加数据!!!!!!!!!!!> * 使用TCP传输文件的服务端: */public class FileUploadServer2 {public static void main(String[] args) {ServerSocket serverSocket = null;final File dir = new File("upload");dir.mkdir();try {serverSocket = new ServerSocket(6789);while(true) {final Socket socket = serverSocket.accept();new Thread() {public void run() {FileOutputStream out = null;try {BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintStream ps = new PrintStream(socket.getOutputStream());String fileName = br.readLine();//接收数据为: 文件名和文件大小;//返回数据为文件的大小,若存在返回实际大小,不存在则返回0long lengthSrc = Long.parseLong(br.readLine());boolean flag = false;//标记是否是续传文件,true为续传,false为正常传输File file = new File(dir, fileName);//Modify: 如文件已存在,再检查文件大小是否一致if( file.exists() ) {//若大小不一致,返回文件大小,以便客户端直接跳过已传输部分if(file.length()==lengthSrc) {ps.println("文件已存在.请不要重复上传!");return;}else {ps.println( file.length() );flag = true;}} else {ps.println(0);}SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time = sdf.format(new Date());String ip = socket.getInetAddress().getHostAddress();long start = System.currentTimeMillis();System.out.println(ip +"上传: <"+file.getName() + ">文件, 在" + time + ( flag ? " 断点续传..." : " 开始上传..."));InputStream in = socket.getInputStream();if(flag) {out = new FileOutputStream(file, true);//注意: 若是断点续传,则应该是追加数据!!!!!!!!!!!} else {out = new FileOutputStream(file);}int len = 0;byte[] b = new byte[1024];while((len= in.read(b))!=-1) {out.write(b, 0, len);}time = sdf.format(new Date());long end = System.currentTimeMillis();System.out.println(ip +"上传: <" + file.getName() + ">文件, 在" + time + ( flag ? " 续传完成, 耗时: " : " 上传完成, 耗时: ") + (end -start) +"毫秒");} catch (IOException e) {e.printStackTrace(); } finally {try {if(out != null) {out.close();}} catch (IOException e) {e.printStackTrace();} finally {try {if(socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}}}.start();}} catch (IOException e) {e.printStackTrace();} finally {try {if(serverSocket != null)serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}



 

原创粉丝点击