TCP传输,客户端和服务器通信

项目说明.txt 外部引用 原始文档
1
2
3
4
TCP服务器提供文件下载服务,服务器支持多线程。
TCP Client从服务器上下载指定的文件,Client也支持多线程。
分服务器代码和客户端代码:ServerOneDownload.java 为服务器代码
DownLoadClient.java为客户端代码、DownFileThread.java为客户端代码
ServerOneDownload.java 外部引用 原始文档
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//file:DownloadServer.java   
import java.net.*;  
import java.io.*;  
class ServerOneDownload extends Thread {  
    private Socket socket = null;  
    private String downloadRoot = null;  
    private static final int Buffer = 8 * 1024;  
    public ServerOneDownload(Socket socket, String downloadRoot) {  
        super();  
        this.socket = socket;  
        this.downloadRoot = downloadRoot;  
        start();  
    }  
    // 检查文件是否真实存在,核对下载密码,若文件不存在或密码错误,则返回-1,否则返回文件长度  
    // 此处只要密码不为空就认为是正确的  
    private long getFileLength(String fileName, String password) {  
        // 若文件名或密码为null,则返回-1  
        if ((fileName == null) || (password == null))  
            return -1;  
        // 若文件名或密码长度为0,则返回-1  
        if ((fileName.length() == 0) || (password.length() == 0))  
            return -1;  
        String filePath = downloadRoot + fileName; // 生成完整文件路径  
        System.out.println("DownloadServer getFileLength----->" + filePath);  
        File file = new File(filePath);  
        // 若文件不存在,则返回-1  
        if (!file.exists())  
            return -1;  
        return file.length(); // 返回文件长度  
    }  
    // 用指定输出流发送指定文件  
    private void sendFile(DataOutputStream out, String fileName)  
            throws Exception {  
        String filePath = downloadRoot + fileName; // 生成完整文件路径  
        // 创建与该文件关联的文件输入流  
        FileInputStream in = new FileInputStream(filePath);  
        System.out.println("DownloadServer sendFile----->" + filePath);  
        byte[] buf = new byte[Buffer];  
        int len;  
        // 反复读取该文件中的内容,直到读到的长度为-1  
        while ((len = in.read(buf)) >= 0) {  
            out.write(buf, 0, len); // 将读到的数据,按读到的长度写入输出流  
            out.flush();  
        }  
        out.close();  
        in.close();  
    }  
    // 提供下载服务  
    public void download() throws IOException {  
        System.out.println("启动下载... ");  
        System.out.println("DownloadServer currentThread--->"  
                + currentThread().getName());  
        System.out.println("DownloadServer currentThread--->"  
                + currentThread().getId());  
        // 获取socket的输入流并包装成BufferedReader  
        BufferedReader in = new BufferedReader(new InputStreamReader(  
                socket.getInputStream()));  
        // 获取socket的输出流并包装成DataOutputStream  
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());  
        try {  
            String parameterString = in.readLine(); // 接收下载请求参数  
            // 下载请求参数字符串为自定义的格式,由下载文件相对于下载根目录的路径和  
            // 下载密码组成,两者间以字符 "@ "分隔,此处按 "@ "分割下载请求参数字符串  
            String[] parameter = parameterString.split("@ ");  
            String fileName = parameter[0]; // 获取相对文件路径  
            String password = parameter[1]; // 获取下载密码  
            // 打印请求下载相关信息  
            System.out.print(socket.getInetAddress().getHostAddress()  
                    + "提出下载请求, ");  
            System.out.println("请求下载文件: " + fileName);  
            // 检查文件是否真实存在,核对下载密码,获取文件长度  
            long len = getFileLength(fileName, password);  
            System.out.println("download fileName----->" + fileName);  
            System.out.println("download password----->" + password);  
            out.writeLong(len); // 向客户端返回文件大小  
            out.flush();  
            // 若获取的文件长度大于等于0,则允许下载,否则拒绝下载  
            if (len >= 0) {  
                System.out.println("允许下载 ");  
                System.out.println("正在下载文件 " + fileName + "... ");  
                sendFile(out, fileName); // 向客户端发送文件  
                System.out.println(fileName +": "+"下载完毕 ");  
            } else {  
                System.out.println("下载文件不存在或密码错误,拒绝下载! ");  
            }  
        } catch (Exception e) {  
            System.out.println(e.toString());  
        } finally {  
            socket.close(); // 关闭socket  
        }  
    }  
    @Override  
    public void run() {  
        try {  
            download();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        // TODO Auto-generated method stub  
        super.run();  
    }  
}  
public class DownloadServer {  
    private final static int port = 65525;  
    private static String root = "C:\\ "; // 下载根目录  
    public static void main(String[] args) throws IOException {  
        String temp = null;  
        // 监听端口  
        try {  
            // 包装标准输入为BufferedReader  
            BufferedReader systemIn = new BufferedReader(new InputStreamReader(  
                    System.in));  
            while (true) {  
                System.out.print("请输入下载服务器的下载根目录: ");  
                root = systemIn.readLine().trim(); // 从标准输入读取下载根目录  
                File file = new File(root);  
                // 若该目录确实存在且为目录,则跳出循环  
                if ((file.exists()) && (file.isDirectory())) {  
                    temp = root.substring(root.length() - 1, root.length());  
                    if (!temp.equals("\\"))  
                        root += "\\";  
                }  
                break;  
            }  
        } catch (Exception e) {  
            System.out.println(e.toString());  
        }  
        ServerSocket serverSocket = new ServerSocket(port);  
        System.out.println("Server start...");  
        try {  
            while (true) {  
                Socket socket = serverSocket.accept();  
                new ServerOneDownload(socket, root);  
            }  
        } finally {  
            serverSocket.close();  
        }  
    }  
}  
DownLoadClient.java 外部引用 原始文档
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//file:DownLoadClient.java   
package org.piaozhiye.study;  
import java.io.IOException;  
import java.net.Socket;  
import android.app.Activity;  
import android.os.Bundle;  
import android.view.View;  
import android.widget.Button;  
import android.widget.EditText;  
public class DownLoadClient extends Activity {  
    private Button download = null;  
    private EditText et_serverIP = null;  
    private EditText et_fileName= null;  
    private String downloadFile = null;  
    private final static int PORT = 65525;  
    private final static String defaultIP = "192.168.0.100";  
    private static String serverIP = null;  
    private Socket socket;  
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        download = (Button)findViewById(R.id.download);  
        et_serverIP= (EditText)findViewById(R.id.et_serverip);  
        et_fileName = (EditText)findViewById(R.id.et_filename);  
        et_serverIP.setText("192.168.0.100");  
        
      download.setOnClickListener(new View.OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                 serverIP = et_serverIP.getText().toString();  
                 if(serverIP == null){  
                     serverIP = defaultIP;  
                 }  
                 System.out.println("DownLoadClient serverIP--->" + serverIP );  
                    System.out.println("DownLoadClient MainThread--->" + Thread.currentThread().getId() );  
                      
                try{  
                    socket = new Socket(serverIP, PORT);  
                      
                }catch(IOException e){  
                      
                }  
                 downloadFile = et_fileName.getText().toString();  
            Thread downFileThread = new Thread(new DownFileThread(socket, downloadFile));  
            downFileThread.start();  
                System.out.println("DownLoadClient downloadFile--->" + downloadFile );  
            }  
        });  
         
    }  
}  
DownFileThread.java 外部引用 原始文档
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package org.piaozhiye.study;  
import java.io.BufferedInputStream;  
import java.io.DataInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.OutputStreamWriter;  
import java.io.PrintWriter;  
import java.net.Socket;  
public class DownFileThread extends Thread {  
    private Socket socket;  
    private String downloadFile;  
    private final static int Buffer = 8 * 1024;  
    public DownFileThread(Socket socket, String downloadFile) {  
        super();  
        this.socket = socket;  
        this.downloadFile = downloadFile;  
    }  
    public Socket getSocket() {  
        return socket;  
    }  
    public void setSocket(Socket socket) {  
        this.socket = socket;  
    }  
    public String getDownloadFile() {  
        return downloadFile;  
    }  
    public void setDownloadFile(String downloadFile) {  
        this.downloadFile = downloadFile;  
    }  
    // 向服务器提出下载请求,返回下载文件的大小  
    private long request(String fileName, String password) throws IOException {  
        // 获取socket的输入流并包装成DataInputStream  
        DataInputStream in = new DataInputStream(socket.getInputStream());  
        // 获取socket的输出流并包装成PrintWriter  
        PrintWriter out = new PrintWriter(new OutputStreamWriter(  
                socket.getOutputStream()));  
        // 生成下载请求字符串  
        String requestString = fileName + "@ " + password;  
        out.println(requestString); // 发出下载请求  
        out.flush();  
        return in.readLong(); // 接收并返回下载文件长度  
    }  
    // 接收并保存文件  
    private void receiveFile(String localFile) throws Exception {  
        // 获取socket的输入流并包装成BufferedInputStream  
        BufferedInputStream in = new BufferedInputStream(  
                socket.getInputStream());  
        // 获取与指定本地文件关联的文件输出流  
        FileOutputStream out = new FileOutputStream(localFile);  
        byte[] buf = new byte[Buffer];  
        int len;  
        // 反复读取该文件中的内容,直到读到的长度为-1  
        while ((len = in.read(buf)) >= 0) {  
            out.write(buf, 0, len); // 将读到的数据,按读到的长度写入输出流  
            out.flush();  
        }  
        out.close();  
        in.close();  
    }  
    // 从服务器下载文件  
    public void download(String downloadFile) throws Exception {  
        try {  
            String password = "password";  
            // String downloadFile ="imissyou.mp3";  
            String localpath = "/sdcard/";  
            String localFile = localpath + downloadFile;  
            long fileLength = request(downloadFile, password);  
            // 若获取的文件长度大于等于0,说明允许下载,否则说明拒绝下载  
            if (fileLength >= 0) {  
                System.out.println("fileLength: " + fileLength + " B");  
                System.out.println("downing...");  
                receiveFile(localFile); // 从服务器接收文件并保存至本地文件  
                System.out.println("file:" + downloadFile + " had save to "  
                        + localFile);  
            } else {  
                System.out.println("download " + downloadFile + " error! ");  
            }  
        } catch (IOException e) {  
            System.out.println(e.toString());  
        } finally {  
            socket.close(); // 关闭socket  
        }  
    }  
    @Override  
    public void run() {  
        System.out.println("DownFileThread currentThread--->"  
                + DownFileThread.currentThread().getId());  
        // TODO Auto-generated method stub  
        try {  
            download(downloadFile);  
        } catch (Exception e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        super.run();  
    }  
      
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值