TCP协议面向连接,提供可靠传输,使用TCP协议传输文件时需要发送方和接收方先经过三次握手建立可靠连接,发送方一边发接收方一边收,传输完成后双方再通过五次挥手断开连接,如果接受方端口没开将导致报错,但能确保数据都能送到接收方手里

    1. import org.apache.commons.io.FileUtils;
    2. import java.io.*;
    3. import java.net.ServerSocket;
    4. import java.net.Socket;
    5. //服务器:接收客户机上传的文件,接收完毕后给客户机回信
    6. public class Server {
    7. public static void serverResponse(String filepath) throws IOException {
    8. //建立服务器
    9. ServerSocket server = new ServerSocket(8888);
    10. System.out.println("服务启动");
    11. //监听端口,随时等待客户机连接,当一个客户机连接后,建立一条线程为其服务,随后继续监听端口
    12. while(true){
    13. System.out.println("等待连接......");
    14. Socket client = server.accept();
    15. String name = client.getLocalSocketAddress().toString();
    16. System.out.println("客户机"+name+"进行了连接");
    17. new Thread(new Channel(client, filepath)).start();
    18. }
    19. }
    20. //封装内部类:多线程处理多个客户机的访问
    21. private static class Channel implements Runnable{
    22. String filepath;
    23. InputStream sis;
    24. DataOutputStream sos;
    25. //构造器
    26. private Channel(Socket client, String filepath) {
    27. try {
    28. //利用IO流进行数据传输
    29. sis = new BufferedInputStream(client.getInputStream());
    30. sos = new DataOutputStream(client.getOutputStream());
    31. } catch (IOException e) {
    32. e.printStackTrace();
    33. }
    34. this.filepath = filepath;
    35. }
    36. //run方法:具体操作
    37. @Override
    38. public void run() {
    39. //具体操作:接收数据
    40. byte[] datas = new byte[1024*10];
    41. int len = 0, i = 1;
    42. File destfile = new File(filepath);
    43. System.out.println("开始接收客户机传来的数据");
    44. while(len != -1) {
    45. try {
    46. len = sis.read(datas);
    47. if(len != -1){
    48. System.out.println("收到第" + i + "个包,大小" + len + "字节");
    49. FileUtils.writeByteArrayToFile(destfile, datas, true);
    50. i++;
    51. }
    52. } catch (IOException e) {
    53. e.printStackTrace();
    54. }
    55. }
    56. try {
    57. //具体操作:给客户机回信
    58. sos.writeUTF("文件已被接收");
    59. System.out.println("STOP");
    60. //释放资源
    61. sis.close();
    62. sos.close();
    63. } catch (IOException e) {
    64. e.printStackTrace();
    65. }
    66. }
    67. }
    68. }
    1. import java.io.*;
    2. import java.net.Socket;
    3. //客户机:向服务器上传文件,并接收服务器的回信
    4. public class Client {
    5. public static void clientRequest(String filepath) throws IOException {
    6. //建立客户机,与服务器建立连接
    7. Socket client = new Socket("localhost", 8888);
    8. System.out.println("已连接服务");
    9. //利用IO流进行数据传输
    10. byte[] flush = new byte[1024*10];
    11. int len, i=1;
    12. InputStream is = new BufferedInputStream(new FileInputStream(filepath));
    13. OutputStream os = new BufferedOutputStream(client.getOutputStream());
    14. while((len = is.read(flush)) != -1){
    15. System.out.println("发送第"+i+"个包");
    16. os.write(flush, 0, len);
    17. os.flush();
    18. i++;
    19. }
    20. //释放Socket的输出流资源,否则在该例子下会导致死锁
    21. //Socket的输出流资源被占用,而服务器需要利用输出流来给客户机回信,故此时服务器会进入阻塞,而客户机又在阻塞状态等待客户机回信,不会继续运行以释放输出流资源
    22. client.shutdownOutput();
    23. //接收服务器回信
    24. DataInputStream dis = new DataInputStream(client.getInputStream());
    25. String result = dis.readUTF();
    26. System.out.println(result);
    27. dis.close();
    28. is.close();
    29. os.close();
    30. client.close();
    31. }
    32. }