Socket编程------TCP文件传输(文档、声音、图片、视频和压缩包等)

本程序是基于TCP稳定传输的文件传输,可以兼容任何类型任何格式的文件传输。

☆基本思路(客户端)

客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。

连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过getInputStream(), getOutputStream()获取即可。

与服务端通讯结束后,关闭Socket。

☆基本思路(服务器端)

服务端需要明确它要处理的数据是从哪个端口进入的。

当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。


当该客户端访问结束,关闭该客户端。

为了兼容所有类型的文件,客户端在发送的时候要求先将文件的后缀名发送过去,一边在服务器端建立正确类型的文件,这就要求客户端发送时要分两次发送,第一次发送后缀名,第二次发送文件正文。在第一次发送完成后要再次一个换行符作为标识符。

而对于服务器方,首先需要开多线程进行接收数据,因为用户是不止一个的,且线程类应实现Runnable接口。在接收后缀名时接收到换行符之后即建立新文件,方便后面输出到该文件中。


代码:

客户端:

package cn.hncu;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JFileChooser;

public class TcpUploadClient {
	
	public static void main(String[] args) {
		JFileChooser jfc=new JFileChooser();
		File file=null;
		int result=jfc.showOpenDialog(null);
		if (result==JFileChooser.APPROVE_OPTION){
			file=jfc.getSelectedFile();
		}
		
		//get the suffix
		int index=file.getName().indexOf(".");
		String suffix=file.getName().substring(index);
		byte suffixBuf[]=suffix.getBytes();
		
		Socket socket=null;
		
		try {
			socket=new Socket("192.168.1.106", 8080);
			//send the suffix first
			OutputStream out=socket.getOutputStream();
			out.write(suffixBuf, 0, suffixBuf.length);
			out.write('\n');
			
			//send the file
			BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
			byte buf[]=new byte[1024];
			int len=0;
			while ((len=bis.read(buf))!=-1){
				out.write(buf, 0, len);
			}
			socket.shutdownOutput();
			out.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}
服务器端:

package cn.hncu;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpUploadServer {
	
	public static void main(String[] args) {
		try {
			ServerSocket server=new ServerSocket(8080);
			while (true){
				Socket socket=server.accept();
				new Thread(new SocketThread(socket)).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class SocketThread implements Runnable{
	private Socket socket;
	
	public SocketThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			File dir=new File("myFiles");
			if (!dir.exists()){
				dir.mkdirs();
			}
			InputStream in=socket.getInputStream();
			
			//this variable "count" is used creating many files with different subscripts
			int count=1;
			File file=null;
			int i=0;
			String suffix;
			byte buf[]=new byte[1024];
			
			while ((buf[i++]=(byte)in.read())!='\n'){
			}
			suffix=new String(buf,0,i-1);
			
			file=new File(dir, "file"+suffix);
			while (file.exists()){
				file=new File(dir, "file("+(count++)+")"+suffix);
			}
			
			int len=0;
			FileOutputStream fos=new FileOutputStream(file);
			while ((len=in.read(buf))!=-1){
				fos.write(buf, 0, len);
			}
			in.close();
			fos.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


  • 5
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值