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