Java实现 Windows Socket TCP实现大文件的传输

一、实验要求

1、在客户端,用户选择本地的某个文件,并发送到服务器端。在服务器端,接收客户端传输的数据流,并按 IP 地址保存在服务器端(文件名重复的,可以覆盖)。2、如果传输过程中服务器端发现客户端断开,服务器端应删除文件,并在屏幕上提示,如“ IP1.2.3.4发来 abcd.txt 文件过程中失去连接。”。如果客户端发现服务器端不工作,客户端应有提示“服务器 1.2.3.5:62345 失去连接”。
 

Java实现 Windows Socket编程 UDP实现大文件的传输参考:

http://blog.csdn.net/qq_24874985/article/details/71305799

二、C/S嵌套字面向TCP的传输流程

三、具体源码

1、Server端

package indi.tangkai.internet.tcp;

import java.net.*;
import java.io.*;

public class Server extends Thread {
	private String dir;// 文件保存路径,在main函数中设置

	private int port;// Socket服务器的端口

	public Server(String dir, int port) {
		this.dir = dir;
		this.port = port;
	}

	@SuppressWarnings("resource" )
	@Override
	public void run()
	{
		Socket socket = null;
		DataInputStream input = null;//这里将socket监听到的数据流作为数据的输入流
		DataOutputStream fileOut = null;//文件输出流
		DataOutputStream ack = null;//作为对client数据传输成功的响应
		int bufferSize = 8192;
        byte[] buf = new byte[bufferSize];//数据存储
        long donelen = 0;//传输完成的数据长度
        long filelen = 0;//文件长度
		try{
			System.out.println("等待连接");
			ServerSocket listen = new ServerSocket(port);//设置端口监听器,在监听到客户端之前,一直堵塞
			do{
				socket = listen.accept();				
				System.out.println("客户端"+ socket.getInetAddress() +"已连接");
				
				//将socket数据作为数据输入流
				input = new DataInputStream(
						new BufferedInputStream(socket.getInputStream()));
				
				//以客户端的IP地址作为存储路径
				String fileDir = dir + "\\" + socket.getInetAddress().toString().substring(1, socket.getInetAddress().toString().length());;
								
				
				File file = new File(fileDir);
				
				//判断文件夹是否存在,不存在则创建
				if(!file.exists())
				{
					file.mkdir();
				}
				
				String fileName = input.readUTF();//读取文件名
				
				//设置文件路径
				String filePath = fileDir + "\\" + fileName;
				
				
				file = new File(filePath);
				
				if(!file.exists())
				{
					file.createNewFile();
				}
				
				fileOut = new DataOutputStream(
                        new BufferedOutputStream(new FileOutputStream(file)));
				
				
				filelen = input.readLong();//读取文件长度

                System.out.println("文件的长度为:" + filelen + "\n");
                System.out.println("开始接收文件!" + "\n");
                ack = new DataOutputStream(socket.getOutputStream());
                
                while (true) {
                    int read = 0;
                    if (input != null) {
                        read = input.read(buf);
                        ack.writeUTF("OK");//结束到数据以后给client一个回复
                    }
                    
                    if (read == -1) {
                        break;
                    }
                    donelen += read;
                    // 下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
                    System.out.println("文件接收了" + (donelen * 100 / filelen)
                            + "%\n");
                    fileOut.write(buf, 0, read);
                }
                
                if(donelen == filelen)
                	System.out.println("接收完成,文件存为" + file + "\n");
                else
                {
                	System.out.printf("IP:%s发来的%s传输过程中失去连接\n",socket.getInetAddress(),fileName);
                	file.delete();
                }
                ack.close();
                input.close();
                fileOut.close();
				
			}while(true);
		}catch (Exception e) {
            System.out.println("接收消息错误" + "\n");
            e.printStackTrace();
            return;
        }
	}

	public static void main(String[] args) {
		Server server = new Server("E:\\test\\download\\tcp\\", 8880);
		server.start();
	}

}


2、client端

package indi.tangkai.internet.tcp;

import java.net.*;
import java.io.*;

public class Client
{
    // 上传的文件保存路径,可在main中修改
    private String dir;
    // socket服务器地址和端口号
    private String host;
    private int port;
    
	public Client(String dir, String host, int port)
	{
		this.dir = dir;
		this.host = host;
		this.port = port;
	}
	
	public void uploadFile(String fileName)
	{
		Socket socket = null;
		
		DataInputStream input = null;//文件输入流
		DataOutputStream output = null;
		DataInputStream getAck = null;//获得服务器的ACK
		int bufferSize = 8192;
        byte[] buf = new byte[bufferSize];//数据存储
		
		try{
			
			socket = new Socket(host, port);//设置socket,并进行连接connect
			
			 // 选择进行传输的文件
            File file = new File(dir + fileName);
            System.out.println("文件长度:" + (int) file.length());
			
			input = new DataInputStream(new FileInputStream(dir + fileName));
			output = new DataOutputStream(socket.getOutputStream());//将socket设置为数据的传输出口
			
			getAck = new DataInputStream(socket.getInputStream());//设置socket数据的来源
			
			//将文件名传输过去
			output.writeUTF(file.getName());
			output.flush();
			//将文件长度传输过去
			output.writeLong((long) file.length());
			output.flush();
			
			int readSize = 0;
			
			while(true)
			{
				if(input != null)
				{
					readSize = input.read(buf);
				}
				if(readSize == -1)
					break;
				
				output.write(buf, 0, readSize);
				
				if(!getAck.readUTF().equals("OK"))
				{
					System.out.println("服务器"+ host + ":" + port + "失去连接!"); 
					break;
				}
			}
            output.flush();
            // 注意关闭socket链接哦,不然客户端会等待server的数据过来,
            // 直到socket超时,导致数据不完整。
            input.close();
            output.close();
            socket.close();
            getAck.close();
            System.out.println("文件传输完成");
			
		}catch (Exception e) {
            e.printStackTrace();
        }
	}
	
	public static void main(String[] args)
	{
		Client client=new Client("E:\\test\\upload\\","127.0.0.1",8880);
		client.uploadFile("test.rar");
	}
}

四、代码运行结果示例图

1、server端


2、client端



  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
以下是Java实现TCP文件传输的示例代码: 服务端代码: ```java import java.io.*; import java.net.*; public class TCPServer { public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器已启动,等待客户端连接..."); while (true) { Socket socket = serverSocket.accept(); System.out.println("客户端已连接,客户端地址:" + socket.getInetAddress().getHostAddress()); // 接收文件名 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String fileName = br.readLine(); System.out.println("客户端请求下载文件:" + fileName); // 发送文件 File file = new File(fileName); if (!file.exists()) { System.out.println("文件不存在!"); socket.close(); continue; } FileInputStream fis = new FileInputStream(file); OutputStream os = socket.getOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { os.write(buffer, 0, len); } fis.close(); os.close(); socket.close(); System.out.println("文件发送完成!"); } } } ``` 客户端代码: ```java import java.io.*; import java.net.*; public class TCPClient { public static void main(String[] args) throws Exception { Socket socket = new Socket("localhost", 8888); System.out.println("连接服务器成功!"); // 发送文件名 String fileName = "C:/temp/1.jpg"; PrintWriter pw = new PrintWriter(socket.getOutputStream()); pw.println(fileName); pw.flush(); // 接收文件 InputStream is = socket.getInputStream(); FileOutputStream fos = new FileOutputStream("C:/temp/2.jpg"); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1) { fos.write(buffer, 0, len); } fos.close(); is.close(); socket.close(); System.out.println("文件接收完成!"); } } ``` 以上代码实现了一个简单的TCP文件传输,服务端监听客户端连接,接收客户端发送的文件名,发送文件给客户端;客户端连接服务端,发送文件名给服务端,接收服务端发送的文件。你可以根据自己的需求对代码进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值