客户端读取本地文件的数据,发送到服务器,服务器接收并存储到文件中
只实现了传送文件的功能。
编写Socket客户端和服务器程序,客户端读取本地文件的数据,发送到服务器,服务器接收并存储到文件中。
消息格式:
字段 长度(单位字节) 内容
--------------------------------------------------------------------
len 8 整个消息长度,不包括这4个字节,类型为long
file_name_length 1 文件名长度,byte
file_name file_name_length 文件名,String
data_length 8 文件数据长度,long
data data_length 文件数据
mac 8 消息的MAC码,byte
客户端执行:
java FileClient -i 192.168.1.171 -p 8888 -f localFileName -r remoteFileName
服务器能连续不断的服务。
服务器端:
1 package test.socket; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.DataInputStream; 6 import java.io.DataOutputStream; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.net.ServerSocket; 10 import java.net.Socket; 11 12 public class FileServer { 13 private int port = 4000; 14 15 public FileServer(int port){ 16 this.port = port; 17 } 18 19 void start(){ 20 Socket socket = null; 21 ServerSocket server = null; 22 DataInputStream inputStream = null; 23 DataOutputStream fileOut = null; 24 long len = 0; 25 int bufferSize = 8192; //缓冲区大小 26 byte[] buf = new byte[bufferSize]; 27 String savePath = null; 28 while (true) { 29 try { 30 server = new ServerSocket(port); 31 socket = server.accept(); 32 System.out.println("建立socket链接"); 33 34 savePath = "d:\\\\"; 35 inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 36 savePath += inputStream.readUTF(); //接收从客户端传来的文件名 37 38 int passedlen = 0; //文件大小 39 len = inputStream.readLong(); //接收从客户端传来的文件的大小 40 fileOut = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))); 41 System.out.println("文件的长度为:" + len + "\n"); 42 System.out.println("开始接收文件!" + "\n"); 43 while (true) { 44 int read = 0; 45 if (inputStream != null) { 46 read = inputStream.read(buf); 47 } 48 passedlen += read; 49 if (read == -1) { //文件末尾 50 break; 51 } 52 //打印传输百分比 53 System.out.println("文件接收了" + (passedlen * 100L/ len) + "%"); 54 fileOut.write(buf, 0, read); 55 } 56 fileOut.close(); 57 inputStream.close(); 58 System.out.println("接收完成,文件存为" + savePath); 59 } 60 //} 61 catch (NumberFormatException e) { 62 e.printStackTrace(); 63 } 64 catch (IOException e){ 65 e.printStackTrace(); 66 } 67 finally{ 68 try { 69 if(null != server){ 70 socket.close(); 71 server.close(); 72 } 73 } 74 catch (IOException e) { 75 e.printStackTrace(); 76 System.out.println("出错了"); 77 } 78 } 79 } 80 } 81 82 public static void main(String[] args){ 83 String usageMsg = "格式错误,请在带参数的eclipse下按照格式输入:\r\n" 84 + "java FileServer -p port"; 85 int port = 4000; //默认端口是4000 86 87 if (2 != args.length){ 88 System.out.println(usageMsg); 89 System.exit(1); 90 } 91 92 for (int i = 0; i < args.length; i++){ 93 if (args[i].equals("-p") || args[i].equals("-P")){ 94 port = Integer.parseInt(args[i+1]); 95 break; 96 } 97 } 98 new FileServer(port).start(); 99 } 100 }
客户端:
package test.socket; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.Socket; public class FileClient { private int port = 4000; //默认短裤为4000 private String ipAddress = "localhost"; //默认地址是本机 private String localFileName; private String remoteFileName; public FileClient(int port,String ipAddress,String localFileName,String remoteFileName){ this.port = port; this.ipAddress = ipAddress; this.localFileName = localFileName; this.remoteFileName = remoteFileName; } void start(){ int bufferSize = 8192; byte[] buf = new byte[bufferSize]; Socket socket = null; //读取文件 DataInputStream is = null; //输出数据到服务器端 DataOutputStream os = null; try { File localFile = new File(localFileName); //本地保存路径,文件名会自动从服务器端继承而来。 socket = new Socket(ipAddress, port); //发送数据到服务器端 is = new DataInputStream(new BufferedInputStream(new FileInputStream(localFileName))); os = new DataOutputStream(socket.getOutputStream()); //传送localFile文件名和remoteFile文件 os.writeUTF(remoteFileName); os.flush(); os.writeLong((long) localFile.length()); os.flush(); while (true) { int read = 0; if (is != null) { read = is.read(buf); } if (read == -1) { break; } os.write(buf, 0, read); } os.flush(); os.close(); is.close(); } catch(IOException e){ e.printStackTrace(); System.out.println("接收消息错误" + "\n"); } finally{ if( null != socket){ try { socket.close(); System.out.println("文件传输完成"); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) { String usageMsg = "格式错误,请在带参数的eclipse下按照格式输入:\r\n" + "java FileClient -i ipAddress" + "-p port -f localFileName -r remoteFileName"; int port = 4000; String ipAddress = null; String localFileName = null; String remoteFileName = null; if(8 != args.length){ System.out.println(usageMsg); System.exit(1); } for(int i = 0; i < args.length; i++){ if(args[i].equals("-p") || args[i].equals("-P")){ port = Integer.parseInt(args[i+1]); } else if(args[i].equals("-i") || args[i].equals("-I")){ ipAddress = args[i+1]; } else if(args[i].equals("-f") || args[i].equals("-F")){ localFileName = args[i+1]; } else if(args[i].equals("-r") || args[i].equals("-R")){ remoteFileName = args[i+1]; } } new FileClient(port,ipAddress,localFileName,remoteFileName).start(); } }