TCP协议面向连接,提供可靠传输,使用TCP协议传输文件时需要发送方和接收方先经过三次握手建立可靠连接,发送方一边发接收方一边收,传输完成后双方再通过五次挥手断开连接,如果接受方端口没开将导致报错,但能确保数据都能送到接收方手里
import org.apache.commons.io.FileUtils;import java.io.*;import java.net.ServerSocket;import java.net.Socket;//服务器:接收客户机上传的文件,接收完毕后给客户机回信public class Server {public static void serverResponse(String filepath) throws IOException {//建立服务器ServerSocket server = new ServerSocket(8888);System.out.println("服务启动");//监听端口,随时等待客户机连接,当一个客户机连接后,建立一条线程为其服务,随后继续监听端口while(true){System.out.println("等待连接......");Socket client = server.accept();String name = client.getLocalSocketAddress().toString();System.out.println("客户机"+name+"进行了连接");new Thread(new Channel(client, filepath)).start();}}//封装内部类:多线程处理多个客户机的访问private static class Channel implements Runnable{String filepath;InputStream sis;DataOutputStream sos;//构造器private Channel(Socket client, String filepath) {try {//利用IO流进行数据传输sis = new BufferedInputStream(client.getInputStream());sos = new DataOutputStream(client.getOutputStream());} catch (IOException e) {e.printStackTrace();}this.filepath = filepath;}//run方法:具体操作@Overridepublic void run() {//具体操作:接收数据byte[] datas = new byte[1024*10];int len = 0, i = 1;File destfile = new File(filepath);System.out.println("开始接收客户机传来的数据");while(len != -1) {try {len = sis.read(datas);if(len != -1){System.out.println("收到第" + i + "个包,大小" + len + "字节");FileUtils.writeByteArrayToFile(destfile, datas, true);i++;}} catch (IOException e) {e.printStackTrace();}}try {//具体操作:给客户机回信sos.writeUTF("文件已被接收");System.out.println("STOP");//释放资源sis.close();sos.close();} catch (IOException e) {e.printStackTrace();}}}}
import java.io.*;import java.net.Socket;//客户机:向服务器上传文件,并接收服务器的回信public class Client {public static void clientRequest(String filepath) throws IOException {//建立客户机,与服务器建立连接Socket client = new Socket("localhost", 8888);System.out.println("已连接服务");//利用IO流进行数据传输byte[] flush = new byte[1024*10];int len, i=1;InputStream is = new BufferedInputStream(new FileInputStream(filepath));OutputStream os = new BufferedOutputStream(client.getOutputStream());while((len = is.read(flush)) != -1){System.out.println("发送第"+i+"个包");os.write(flush, 0, len);os.flush();i++;}//释放Socket的输出流资源,否则在该例子下会导致死锁//Socket的输出流资源被占用,而服务器需要利用输出流来给客户机回信,故此时服务器会进入阻塞,而客户机又在阻塞状态等待客户机回信,不会继续运行以释放输出流资源client.shutdownOutput();//接收服务器回信DataInputStream dis = new DataInputStream(client.getInputStream());String result = dis.readUTF();System.out.println(result);dis.close();is.close();os.close();client.close();}}
