要件:各クライアントの開始後にサーバーにファイルをアップロードでき、アップロードはファイルを受信した後、ディレクトリサーバに保存されました。クライアントは、同時に複数のファイルのアップロードを受け取ることができます。
分析:
(1)サーバに「同時」処理を要求する複数のクライアントは、クライアントがハンドルに別のスレッドを必要と通信し、それぞれが複数のスレッドを使用する必要があります。
(2)あなたは一意のファイル名を確保する必要があるので、同じ名前を送信することができ、サーバへのクライアントごとに一つだけのアップロード、ファイルをアップロードするファイルを保存したサーバディレクトリ。私たちは、ファイル名と拡張子を変更しないよう、「タイムスタンプ」を使用することができます
(3)クライアントが(拡張子を含む)サーバー名にファイルとファイルの内容をアップロードする必要があります。ファイル名は必ずしも文字列ではなく、DataOutputStreamのとはDataInputStreamを選択するプレーンテキストとして、文書の内容、です。
クライアントのコード例:
1つの インポートjava.io.BufferedReader。
2 インポートjava.io.DataOutputStreamのメソッド。
3 インポートのjava.io.File;
4 インポートjava.io.FileInputStream。
5 輸入java.io.InputStreamを。
6 インポートjava.io.InputStreamReader。
7 インポートにjava.io.OutputStream。
8 インポートのjava.net.Socket。
9 インポートjava.util.Scanner。
10
11 パブリック クラスクライアント{
12 公共 静的 ボイドメイン(文字列[]引数)がスロー{例外
13は、 // (1)サーバに接続された
14 =ソケットソケット新しい新しいソケット(「192.168.54.68」、8888 );
15
16 スキャナ入力= 新しい新しいスキャナ(System.in);
17
18れる // (2)キーボードからファイル入力パスと名前
19 System.out.print( "アップロードするファイルを選択してください:" );
20 文字列のパス= input.nextLine();
21 ファイルファイル= 新しい新しいファイル(パス);
22
23 のOutputStream OUT = Socket.getOutputStream ();
24 DataOutputStreamをDOSは= 新しい新DataOutputStreamを(OUT); // その目的で、単一の文字列を渡すのいずれかですが、またバイトの内容を書くために
25
26です // (拡張子を含む)のファイル名を送信するために
27 dos.writeUTF(file.getName() ); // 単一の送信ストリング
28
29 //は、ファイルから読み込まIOストリームを、必要は、サーバは、最後に送信する
30 のFileInputStream FIS = 新しい新しいFileInputStreamを(ファイル)
31が
32 // ファイルの内容に(3)。過去に渡されたサーバ、ファイルコピーに似
33は バイト [] =データ新しい新しい バイト [1024 ];
34は 、一方(真の){
35 INT LEN = fis.read(データ)
36 IF(LEN == - 1 ){
37 [ BREAK ;
38である }
39 dos.write(データ、0 、LEN);
40 }
41は socket.shutdownOutput();
42は、
43である // 結果(4)を受信するサーバによって返された
44である 入力ストリームは= IS Socket.getInputStream();
45 InputStreamReaderのISR = 新しい新しい InputStreamReaderの(IS); // 文字ストリーム、バイトストリームに
46がある BufferedReaderのBR = 新しい新しいをBufferedReader(ISR);
47 文字列の結果= br.readLine();
48 System.out.println(結果)。
49
50 // (5)关闭
51 fis.close()。
52 input.close()。
53 socket.close()。
54 }
55 }
サーバーのサンプルコード:
1 import java.net.ServerSocket;
2 import java.net.Socket;
3
4 public class Server {
5 public static void main(String[] args) throws Exception{
6 //服务器在8888端口号监听数据
7 @SuppressWarnings("resource")
8 ServerSocket server = new ServerSocket(8888);
9
10 while(true){
11 //(2)等待连接
12 //这句代码执行一次,意味着一个客户端连接
13 Socket accept = server.accept();
14
15 FileUploadThread ft = new FileUploadThread(accept);
16 ft.start();
17 }
18 }
19 }
服务器端处理每一个客户端上传文件的线程类代码:
1 import java.io.DataInputStream;
2 import java.io.FileNotFoundException;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.io.PrintStream;
8 import java.net.Socket;
9 import java.text.SimpleDateFormat;
10 import java.util.Date;
11
12 public class FileUploadThread extends Thread{
13 private Socket socket;
14 private String dir = "upload/";
15
16 public FileUploadThread(Socket socket) {
17 super();
18 this.socket = socket;
19 }
20
21 public void run(){
22 FileOutputStream fos = null;
23 try {
24 InputStream is = socket.getInputStream();
25 DataInputStream dis = new DataInputStream(is);
26
27 //读取文件名(含后缀名)
28 String filename = dis.readUTF();
29 //截取后缀名
30 String ext = filename.substring(filename.lastIndexOf("."));
31 //生成时间戳
32 SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
33 filename = sf.format(new Date());
34 //用新文件路径构建文件输出流
35 fos = new FileOutputStream(dir + filename + ext);
36 //接收文件内容
37 byte[] data = new byte[1024];
38 while(true){
39 int len = is.read(data);
40 if(len==-1){
41 break;
42 }
43 fos.write(data, 0, len);
44 }
45
46 //返回结果
47 OutputStream out = socket.getOutputStream();
48 PrintStream ps = new PrintStream(out);
49 ps.println(filename + ext + ":已上传完毕");
50 } catch (FileNotFoundException e) {
51 e.printStackTrace();
52 } catch (IOException e) {
53 e.printStackTrace();
54 }finally{
55 try {
56 fos.close();
57 socket.close();
58 } catch (IOException e) {
59 e.printStackTrace();
60 }
61 }
62 }
63 }