
idea服务端更新

为了防止代码量上升可能带来的结构杂乱,我们对服务端架构进行优化,server包负责socket服务基础实现,data包负责处理各种安卓端的命令。
将readsocketmsg,writebackmsg方法单独拿出,创建一个socketmsg方法类,专门负责数据流的读取与写入。
socketmsg.java
package lrz.server;
import java.io.*;
import java.net.socket;
import java.util.arraylist;
public class socketmsg {
public static arraylist<string> readsocketmsg(socket socket) throws ioexception {
arraylist<string> msglist=new arraylist<string>();
inputstream inputstream = socket.getinputstream();
inputstreamreader reader = new inputstreamreader(inputstream, "utf-8");
bufferedreader bufferedreader=new bufferedreader(reader);
string linenumstr = bufferedreader.readline();
int linenum=integer.parseint(linenumstr);
for(int i=0;i<linenum;i++){
string str = bufferedreader.readline();
msglist.add(str);
}
//读取结束后,输入流不能关闭,此时关闭,会将socket关闭,从而导致后续对socket写操作无法实现
return msglist;
}
public static void writebackmsg(socket socket, arraylist<string> msgbacklist) throws ioexception {
bufferedoutputstream os = new bufferedoutputstream(socket.getoutputstream());
outputstreamwriter writer=new outputstreamwriter(os,"utf-8");
writer.write(""+msgbacklist.size()+"\n"); //未真正写入的输出流,仅仅在内存中
writer.flush(); //写入输出流,真正将数据传输出去
for(int i=0;i<msgbacklist.size();i++){
writer.write(msgbacklist.get(i)+"\n");
writer.flush();
}
}
}
创建netfiledata.java作为文件夹访问的方法类,将exedir()方法放入其中。
netfiledata.java
package lrz.data;
import java.io.file;
import java.text.simpledateformat;
import java.util.arraylist;
import java.util.date;
public class netfiledata {
public static arraylist<string> exedir(string cmdbody) throws exception {
// todo auto-generated method stub
arraylist<string> backlist=new arraylist<string>();
file file = new file(cmdbody);
file[] listfiles = file.listfiles();
for(file mfile:listfiles){
string filename = mfile.getname();
long lastmodified = mfile.lastmodified();//获取文件修改时间
simpledateformat dateformat = new simpledateformat("yyyy-mm-dd hh:mm:ss");//给时间格式,例如:2018-03-16 09:50:23
string filedate = dateformat.format(new date(lastmodified));//取得文件最后修改时间,并按格式转为字符串
string filesize="0";
string isdir="1";
if(!mfile.isdirectory()){//判断是否为目录
isdir="0";
filesize=""+mfile.length();
}
backlist.add(filename+">"+filedate+">"+filesize+">"+isdir+">");
}
return backlist;
}
}
serversocket01.java主函数则将以上方法移除,改为调用
package lrz.server;
import lrz.data.netfiledata;
import java.io.*;
import java.net.inetaddress;
import java.net.networkinterface;
import java.net.serversocket;
import java.net.socket;
import java.util.arraylist;
import java.util.enumeration;
public class serversocket01 {
int port = 8019;// 自定义一个端口,端口号尽可能挑选一些不被其他服务占用的端口,祥见http://www.51sjk.com/Upload/Articles/1/0/246/246054_20210619000344573.jpg
static int connect_count = 0;// 连接次数统计
arraylist<string> msgbacklist;
public serversocket01() {
// todo auto-generated constructor stub
}
public serversocket01(int port) {
super();
this.port = port;
}
private void printlocalip(serversocket serversocket) {// 枚举打印服务端的ip
try {
system.out.println("服务端命令端口prot=" + serversocket.getlocalport());
enumeration<networkinterface> interfaces = null;
interfaces = networkinterface.getnetworkinterfaces();
while (interfaces.hasmoreelements()) {
networkinterface ni = interfaces.nextelement();
enumeration<inetaddress> addresss = ni.getinetaddresses();
while (addresss.hasmoreelements()) {
inetaddress nextelement = addresss.nextelement();
string hostaddress = nextelement.gethostaddress();
system.out.println("本机ip地址为:" + hostaddress);
}
}
} catch (exception e) {
e.printstacktrace();
}
}
public void work() throws ioexception {
// 注意:由于socket的工作是阻塞式,android端socket的工作必须在新的线程中实现,若在ui主线程中工作会报错
serversocket serversocket = new serversocket(port);
printlocalip(serversocket);
while (true) {// 无限循环,使之能结束当前socket服务后,准备下一次socket服务
system.out.println("waiting client to connect.....");
socket socket = serversocket.accept();// 阻塞式,直到有客户端连接进来,才会继续往下执行,否则一直停留在此代码
system.out.println("client connected from: "
+ socket.getremotesocketaddress().tostring());
arraylist<string> cmdlist= socketmsg.readsocketmsg(socket);
cmdlist.foreach(s -> system.out.println(s));
string cmdbody=cmdlist.get(0);
try {
msgbacklist= netfiledata.exedir(cmdbody);
} catch (exception e) {
e.printstacktrace();
}
msgbacklist.foreach(s -> system.out.println(s));
socketmsg.writebackmsg(socket,msgbacklist);
socket.close();
system.out.println("当前socket服务结束");
}
}
/**
* @param args
*/
public static void main(string[] args) {
// todo auto-generated method stub
try {
new serversocket01().work();
} catch (ioexception e) {
// todo auto-generated catch block
e.printstacktrace();
}
}
}
安卓端更新
使用listview显示文件夹内容,并且实现动态访问。
mainactivity.java更新了简单的listview显示,设立互动事件,在点击某个列表部分时向服务端发动指定命令,返回结果后更新列表,实现互动效果。
package com.example.android_app;
import androidx.appcompat.app.appcompatactivity;
import android.os.bundle;
import androidx.annotation.nonnull;
import android.os.build;
import android.os.handler;
import android.os.message;
import android.view.view;
import android.widget.adapterview;
import android.widget.arrayadapter;
import android.widget.button;
import android.widget.edittext;
import android.widget.listview;
import android.widget.textview;
import android.widget.toast;
import java.util.arraylist;
public class mainactivity extends appcompatactivity {
public static final string key_server_ack_msg = "key_server_ack_msg";
private handler handler = null;
edittext url,way,dir;
listview lv;
button submit;
socketclient socketclient=null;
string here;
arraylist<string> data;
int port;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
url=findviewbyid(r.id.url);
way=findviewbyid(r.id.way);
dir=findviewbyid(r.id.dir);
lv=findviewbyid(r.id.listview);
submit=findviewbyid(r.id.submit);
handler=new handler(new handler.callback() {
@override
public boolean handlemessage(@nonnull message msg) {
bundle data_bundle = msg.getdata();
data=data_bundle.getstringarraylist(key_server_ack_msg);
data=datamaker();
printadapter(data);
return false; }
});
submit.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
port=integer.parseint(way.gettext().tostring());
here=dir.gettext().tostring();
getdata();
}
});
lv.setonitemclicklistener(new adapterview.onitemclicklistener() {
@override
public void onitemclick(adapterview<?> parent, view view, int position, long id) {
here=here+"/"+data.get(position);
getdata();
}
});
}
private void getdata() {
socketclient=new socketclient(url.gettext().tostring(),port,handler);
socketclient.work(here);
}
private arraylist<string> datamaker() {
arraylist<string> dataresult=new arraylist<>();
int i=data.size();
for (int j = 0; j <i ; j++) {
string str=data.get(j);
str=str.substring(0,str.indexof(">"));
dataresult.add(str);
}
return dataresult;
}
private void printadapter(arraylist<string> data) {
arrayadapter<string> arrayadapter=new arrayadapter<>(this,android.r.layout.simple_list_item_1,data);
lv.setadapter(arrayadapter);
}
}
socketclient.java无变动
activity_main.xml布局添加listview,代替原先的textview
<?xml version="1.0" encoding="utf-8"?>
<linearlayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<linearlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<edittext
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:id="@+id/url"
android:text="服务端ip"/>
<edittext
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:id="@+id/way"
android:text="8019"/>
</linearlayout>
<edittext
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/dir"
android:text="d://"/>
<button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="submit"
android:id="@+id/submit"/>
<listview
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listview"/>
</linearlayout>
补充一点:
安卓端访问的ip在服务端中查看,ip为服务端网络ip,我是红色圈中的,可以都试一下,一般都是倒数第二个长得像ip的这个,port在服务端主函数中设置,可以是任何数,8019为常用端

以上就是android socket如何实现文件列表动态访问的详细内容,更多关于android socket实现列表动态访问的资料请关注其它相关文章!
訫蓒