您现在的位置是:首页 >技术教程 >Android: 在wsl中使用libevent实现http服务器,并编写Android app 实现文件下载网站首页技术教程
Android: 在wsl中使用libevent实现http服务器,并编写Android app 实现文件下载
在wsl中使用libevent实现http服务器,并编写Android app 实现文件下载
PC端:
- 在WSL中编译libevent-2.1.8-stable sample中的http-server.c,实现http测试用服务器
- Makefile如下:
#指定源文件为*.c
src = $(wildcard *.c)
#通过src生成中间需要的汇编文件名,把src中.c替换为.o
obj = $(patsubst %.c, %.o, $(src))
#指定最后生成的可执行文件a.out
target = http-server
#ALL代表搜索依赖,一直查找到文件尾部
ALL:$(target)
#再链接汇编文件生成可执行文件a.out
(
t
a
r
g
e
t
)
:
(target):
(target):(obj)
gcc $^ -o $@ -L./ -ljson-c -L./ -levent
#-L./ -levent
#-L./ -lpthread
#-L./ -lpthread
#先生成汇编文件.o
%.o:%c
gcc -c $< -o $@
#clean命令,清除目标文件(a.out)和中间生成的汇编文件(*.o)
clean:
-rm -rf $(target) $(obj)
#生成伪目标,防止makefile所在文件目录中有clean, a.out等干扰文件
.PHONY : clean ALL
- 注意启动时要加上服务器默认的文件目录,这里是dump
- 服务器默认的文件目录内容如下:
Android Studio端:
- AndroidMainfest 添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- activity_main.xml文件:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bt_check_SD"
android:text="检测SD卡"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bt_download_file"
android:layout_below="@+id/bt_check_SD"
android:text="下载文件"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_below="@id/bt_download_file"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- MainActivity.java文件:
package com.example.file_download;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity: ";
private String urlLoadPath = “http://10.0.2.2:7777/test.txt”; //下载的文件 网络地址
private String savaDirPath = “testLoad”; //保存的地址
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View.OnClickListener myClickListener = new MyClickListener();
Button bt_ck = findViewById(R.id.bt_check_SD);
Button bt_dw = findViewById(R.id.bt_download_file);
bt_ck.setOnClickListener(myClickListener);
bt_dw.setOnClickListener(myClickListener);
}
private class MyClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_check_SD:
Thread t_ck_sd = new Thread(){
@Override
public void run() {
Log.e(TAG," checkPermission run");
checkPermission();
}
};
t_ck_sd.start();
Toast.makeText(MainActivity.this, "bt_ck", Toast.LENGTH_SHORT).show();
break;
case R.id.bt_download_file:
Thread t_dw_file = new Thread(){
@Override
public void run() {
Log.e(TAG," DownLoadFileFormUrl run");
DownLoadFileFormUrl(urlLoadPath,savaDirPath);
}
};
t_dw_file.start();
Toast.makeText(MainActivity.this,"bt_download_file",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
//sd 卡权限申请
private void checkPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE},100);
}
return;
}
public boolean DownLoadFileFormUrl(String urlLoadPath, String savaDirPath){
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
HttpURLConnection httpURLConnection = null;
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
Log.i(TAG," 未安装 SD 卡");
return false;
}
File pathSd = Environment.getExternalStorageDirectory(); //获取 SD 卡路径
File fileRealDirectoty = new File(pathSd.getAbsolutePath() + File.separator + savaDirPath);
Log.i(TAG,"文件保存的真正目录: " + fileRealDirectoty);
if (!fileRealDirectoty.exists()) { //如果目录 不存在 ,就创建
Log.i(TAG,"创建 存储文件夹");
fileRealDirectoty.mkdirs();
}
//获取要下载的文件名称,在这里可以更改下载的文件名
String fileName = urlLoadPath.substring(urlLoadPath.lastIndexOf("/") + 1);
//String fileName = "test.zip";
//创建 这个文件名 命名的 file 对象
File file = new File(fileRealDirectoty,fileName);
Log.i(TAG,"file: " + file);
if (!file.exists()) { //倘若没有这个文件
try {
Log.i(TAG,"创建文件");
file.createNewFile(); //创建这个文件
} catch (IOException e) {
e.printStackTrace();
}
}
try {
URL url = new URL(urlLoadPath);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
int code = httpURLConnection.getResponseCode();
if (code == 200) {
//网络连接成功
} else {
//网络返回异常
}
//根据响应获取文件大小
int fileSize = httpURLConnection.getContentLength();
Log.i(TAG,"文件大小: " + fileSize);
inputStream = httpURLConnection.getInputStream();
fileOutputStream = new FileOutputStream(file);
byte[] b = new byte[1024];
int tem = 0;
while ((tem = inputStream.read(b))!= -1) {
fileOutputStream.write(b,0,tem);
}
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i(TAG,"文件下载 成功");
return true;
}
}
Android端结果:
在Device Manager中找到/storage/emulated/0/testLoad这个目录可以看到下载的文件。