这里有新鲜出炉的Java并发编程示例,程序狗速度看过来!
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
这篇文章主要为大家详细介绍了java如何基于Socket制作一个简单下载器,感兴趣的小伙伴们可以参考一下
1.首先要建立一个服务器用来处理信息并给客户端传输文件(电脑)
我是用电脑开了一个WIFI,手机连上后使用scoket传输的
SERVERIP要根据自己实际情况更改。端口也可以随便更改0~65535,尽量选大一点
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.net.ServerSocket;
- import java.net.Socket;
- /**
- * 测试Android客户端与PC服务器通过socket进行交互 服务器端:接收客户端的信息并回送给客户
- *
- * @author Ameyume
- *
- */
- public class Server implements Runnable {
- //定义传输的IP和端口信息
- public static final String SERVERIP = "192.168.155.1";
- //定义的9888端口
- public static final int SERVERPORT = 9888;
- //定义文件
- private File file = null;
- public static void main(String[] args) {
- //建立调用线程执行传输的方法
- Thread desktopServerThread = new Thread(new Server());
- desktopServerThread.start();
- }
- public void run() {
- try {
- System.out.println("S: Connecting...9888");
- //创建套接字
- ServerSocket serverSocket = new ServerSocket(SERVERPORT);
- while (true) {
- // 等待接受客户端请求
- Socket client = serverSocket.accept();
- System.out.println("S: Receiving...9888");
- try {
- // 接受客户端信息
- BufferedReader in =new BufferedReader(new InputStreamReader(client.getInputStream()));
- System.out.println("S: 接收客户端信息");
- // 读取客户端的信息
- String str = in.readLine();
- String str1 = str.substring(0, 2);
- String str2 = str.substring(2);
- System.out.println(str);
- //根据客户端的请求找到对应的文件并把文件大小的值传过去
- if (str.equals("file_size")) {
- //定义你要传输的文件(我这里写的是E盘下的某个文件)
- file = new File("E:\\某个文件");
- //输入流
- FileInputStream fis = new FileInputStream(file);
- //输出流
- BufferedInputStream bis = new BufferedInputStream(fis);
- //计算将要传输的文件大小
- int sum = bis.available();
- //将int型的文件大小转成字符串
- String s = String.valueOf(sum);
- System.out.println(s);
- //建立输出流以发送文件大小的信息
- PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
- //发送文件的大小信息
- out.println(s);
- //关闭流
- out.flush();
- bis.close();
- } else if (str1.equals("ok")) {
- int a = Integer.parseInt(str2);
- // 客户端收到文件大小的值后,再根据客户端传来的“ok”将文件传过去
- BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
- System.out.println("S: 开始传输");
- //开始传输
- if (true) {
- //输入流
- FileInputStream fis = new FileInputStream(file);
- //跳过前面已经传输过的字节
- fis.skip(a);
- //缓冲输入流
- BufferedInputStream bis = new BufferedInputStream(fis);
- int t = -1;
- while ((t = bis.read()) >= 0) {
- bos.write(t);
- }
- String s = "已传输";
- //关闭流
- bos.flush();
- bis.close();
- bos.close();
- // serverSocket.close();
- System.out.println("S: Received: '" + s + "'");
- }
- } else {
- System.out.println("Not receiver anything from client!");
- }
- } catch(Exception e) {
- System.out.println("S: Error 1");
- e.printStackTrace();
- } finally {
- client.close();
- System.out.println("S: Done.");
- }
- }
- } catch(Exception e) {
- System.out.println("S: Error 2");
- e.printStackTrace();
- }
- }
- }
2.再建立一个客户端,我这里用的是安卓写的MainActivity.java(我是在手机上运行的)
- package com.xhy.zz;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- // 定义Handler
- public static Handler myHandler;
- // 定义intent
- private Intent intent;
- // 获取控件
- private TextView text_name;
- private TextView text_percent;
- private Button btn_start;
- private Button btn_stop;
- // 文件显示
- private TextView text_sel_file;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- text_name = (TextView) findViewById(R.id.text_name);
- text_percent = (TextView) findViewById(R.id.text_percent);
- btn_start = (Button) findViewById(R.id.btn_start);
- btn_stop = (Button) findViewById(R.id.btn_stop);
- // 按钮一的返回信息,显示进度
- myHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == 0x0001) {
- Bundle data = msg.getData();
- String str = data.getString("value");
- text_percent.setText(str);
- }
- }
- };
- // 显式的方式调用HelloService
- intent = new Intent(this, DownService.class);
- // 设置启动按钮点击事件
- btn_start.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // 开启服务
- startService(intent);
- }
- });
- // 设置停止按钮点击事件
- btn_stop.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // 关闭服务
- stopService(intent);
- }
- });
- }
- /***
- * 被调用Activity一旦返回值 该回调方法将被系统自动调用
- */
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent intent) {
- super.onActivityResult(requestCode, resultCode, intent);
- // 如果请求码是0
- // 并且返回的结果码为1
- // 请求的Activity可能返回多种结果码
- if (requestCode == 0 && resultCode == 1) {
- // 取出数据
- Bundle data = intent.getExtras();
- String str = data.getString("files");
- // 显示数据
- text_sel_file.setText(str);
- }
- }
- }
3.activity_main.xml文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/text_name"
- android:layout_width="160dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="1" />
- <TextView
- android:id="@+id/text_percent"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="20dp"
- android:text="0%"/>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="20dp"
- android:orientation="vertical" >
- <Button
- android:id="@+id/btn_start"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="start"
- />
- <Button
- android:id="@+id/btn_stop"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="stop"
- />
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
4.DownService用于在后台开启线程执行下载
- package com.xhy.zz;
- import java.io.BufferedInputStream;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.net.InetAddress;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.IBinder;
- import android.os.Message;
- import android.util.Log;
- public class DownService extends Service {
- private static final String TAG = "Socket_Android";
- // Preferece机制操作的文件名
- public static final String PREFERENCE_NAME = "DownService";
- // Preferece机制的操作模式
- public static int MODE = Context.MODE_PRIVATE;
- // 线程
- private Thread workThread;
- // 定义文件名
- private String filename = "file";
- // 端口号
- private int port = 9888;
- private boolean isStop = false;
- /***
- * 必须要实现的方法
- */
- @Override public IBinder onBind(Intent intent) {
- return null;
- }
- @Override public void onCreate() {
- super.onCreate();
- }
- @Override public int onStartCommand(Intent intent, int flags, int startId) {
- Log.v("TCP", filename);
- // 建立传输的方法
- Runnable backgroundWork = new Runnable() {@Override public void run() {
- // setTitle("测试Socket连接");
- Socket socket = null;
- Socket socket1 = null;
- try {
- /*
- * 指定Server的IP地址,此地址为局域网地址,如果是使用WIFI上网,则为PC机的WIFI IP地址
- * 在ipconfig查看到的IP地址如下: Ethernet adapter 无线网络连接:
- * Connection-specific DNS Suffix . : IP Address. . . .
- * . . . . . . . . : 192.168.155.1
- */
- InetAddress serverAddr = InetAddress.getByName("192.168.155.1"); // TCPServer.SERVERIP
- Log.d("TCP", "C: Connecting...");
- Log.d("TCP", filename + " " + port);
- // 应用Server的IP和端口建立Socket对象,向服务端发送请求获取文件大小的值
- socket1 = new Socket(serverAddr, port);
- String message = "---Test_Socket_Android---";
- Log.d("TCP", "C: Sending: '" + message + "'");
- // 将信息通过这个对象来发送给Server
- PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream())), true);
- // 把用户输入的内容发送给server
- out.println("file_size");
- out.flush();
- // 接收服务器信息
- BufferedReader in =new BufferedReader(new InputStreamReader(socket1.getInputStream()));
- // 获取文件大小
- String str1 = in.readLine();
- Log.d("TCP", str1);
- // 将文件大小转成int型
- int sum = Integer.parseInt(str1);
- Log.d("TCP", str1);
- // 关闭输入流
- in .close();
- SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCE_NAME, MODE);
- SharedPreferences.Editor editor = sharedPreferences.edit();
- //取出已经传输了的字节
- int pre = sharedPreferences.getInt("DownService", 0);
- int _pre = pre;
- //将其转化为字符串以便发送给服务端
- String s = String.valueOf(_pre);
- // 应用Server的IP和端口建立Socket对象再次向服务端发送请求,以获取文件内容
- socket = new Socket(serverAddr, port);
- // 向服务端发送请求获得文件的字符
- PrintWriter out1 = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
- out1.println("ok" + s);
- out1.flush();
- out.close();
- // 定义输入流
- BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
- String file1 = filename;
- String file;
- // 判断手机是否插入了SDCard,是则将文件插入内存卡
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- File sdCard = Environment.getExternalStorageDirectory();
- // SD卡定义文件
- file = sdCard.getCanonicalFile() + "/" + file1;
- // 定义文件输出流
- FileOutputStream fos = new FileOutputStream(file, true);
- try {
- int t = -1;
- int downloaded = pre;
- // 定义每次传输的字节数
- byte[] buff = new byte[8192];
- Log.i("sum", sum + "");
- // 开始将服务端的文件写入手机SD卡中
- while ((t = bis.read(buff)) != -1) {
- if (isStop == true) {
- break;
- }
- fos.write(buff, 0, t);
- downloaded += t;
- //将传输的进度存储起来
- editor.putInt("DownService", downloaded);
- editor.commit();
- //当传完了则把存储信息归零
- if (downloaded == sum) {
- editor.putInt("DownService", 0);
- editor.commit();
- }
- // 获得文件传输的进度
- float wb = ((downloaded * 100) / (float) sum);
- int wi = (int) wb;
- System.out.println(downloaded);
- String str = String.valueOf(wi) + "%";
- // 将文件的传输进度给送给BaseActivity,以显示给用户
- Message msg = new Message(); // 生成消息
- // 生成消息
- msg.what = 0x0001; // 设置消息类型
- // 生成Bundle携带数据
- Bundle data = new Bundle();
- data.putString("value", str);
- msg.setData(data);
- // 利用Handler发送消息
- MainActivity.myHandler.sendMessage(msg);
- }
- // 关闭输入输出流
- bis.close();
- fos.flush();
- fos.close();
- } catch(Exception e) {
- bis.close();
- fos.flush();
- fos.close();
- }
- }
- Log.d(TAG, "From server:'已接收" + "'");
- } catch(UnknownHostException e) {
- Log.e(TAG, "192.168.155.1 is unkown server!");
- } catch(Exception e) {
- e.printStackTrace();
- } finally {
- try {
- socket.close();
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- }
- };
- workThread = new Thread(backgroundWork);
- // isAlive方法用于判断workThread线程是否被开启
- if (!workThread.isAlive()) {
- // 生成新线程
- workThread.start();
- Log.v("ServiceLife", "线程开始工作");
- } else {
- Log.v("workThread", "线程已经被调用");
- }
- return START_STICKY;
- }
- @Override public void onDestroy() {
- super.onDestroy();
- // 利用interrupt方式中断该线程
- isStop = true;
- Log.v("ServiceLife", "onDestroy方法被调用");
- }
- }
5、最后别忘了注册AndroidManifest.xml
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS">
- </uses-permission>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
- </uses-permission>
- <service android:name=".DownService">
- </service>
来源: http://www.phperz.com/article/17/1112/360154.html