本程序是基于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();
}
}
}