本文实例为大家分享了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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持phpstudy。
本文地址:https://www.stayed.cn/item/15677
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我