[原创]实现android控制PC
首先建立服务端:利用socket通信持续监听客户端发来的消息再做相应的操作
public class Pc_service {
static ServerSocket serversocket = null;// 服务socket
static DataInputStream data_input = null;// 输入流
static DataOutputStream data_output = null;// 输出流
public static void main(String[] args) {
try {
//开启WiFi
startNet();
// 监听30000端口
serversocket = new ServerSocket(30000);
System.out.println("listening 30000 port");
while (true) {
// 获取客户端套接字
Socket client_socket = serversocket.accept();
String send_msg = "";
try {
// 获取输入流,读取客户端传来的数据
data_input = new DataInputStream(client_socket
.getInputStream());
String msg = data_input.readUTF();
System.out.println(msg);
// 判断输入,进行相应的操作
data_output = new DataOutputStream(client_socket
.getOutputStream());
if ("shutdown".equals(msg)) {
Shutdown();
// 发送消息回Android端
send_msg = "60秒后关机 ";
} else if ("restart".equals(msg)) {
Restart();
send_msg = "60秒后重启";
} else if ("cancel".equals(msg)) {
cancel();
send_msg = "关机已取消";
}
} catch (Exception e) {
// TODO: handle exception
} finally {
try {
if (data_output != null) {
data_output.writeUTF(send_msg);
data_output.close();
}
data_input.close();
// 关闭连接
client_socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
//打开承载网络
private static void startNet()throws IOException{
Process p = Runtime.getRuntime().exec("netsh wlan start hostednetwork");
}
// 关机
private static void Shutdown() throws IOException {
Process p = Runtime.getRuntime().exec("shutdown -s -t 60");
System.out.println("shutdown ,60 seconds later ");
}
// 重启
private static void Restart() throws IOException {
Process p = Runtime.getRuntime().exec("shutdown -r -t 60");
System.out.println("restart ,60 seconds later ");
}
// 取消登陆
private static void cancel() throws IOException {
Process p = Runtime.getRuntime().exec("shutdown -a");
System.out.println("cancel ");
}
}服务端还是比较简单的,
下面来看客户端的操作,先看下界面

在启动app进入ScanActivity,这个activity的作用是扫描当前网段内哪些PC开了30000端口(端口可以自己设定,但必须与服务端保持一致),一旦找到则把那个IP保存下来并发给MainActivity处理。这里有几点需要说一下。
在ScanActivity中,首先需要知道当前网段的主机IP,可以通过context.getSystemService(Context.WIFI_SERVICE);拿到WiFiManager实例,进而可以DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();拿到DhcpInfo的实例,在DhcpInfo中有个属性serverAddress,保存着服务端的IP,但是是int类型的需要稍微转换一下,顺便说一下,在另一个属性ipAddress中保存着当前手机被分配到的IP(当然是内网中的)~
拿到服务端IP后就可以截取IP前三个(例如192.168.1.*),前面192.168.1就是所在网段,后面那个“*”就可以自己写了,这里我用for循环,从192.168.1.1到192.168.1.254依次遍历并尝试连接,尝试连接可以用
Socket socket = new Socket(); InetSocketAddress s = new InetSocketAddress(resultIP+i, 30000); socket.connect(s,50);
new InetSocketAddress(resultIP+i, 30000);表示获得个服务端的IP和端口的Socket,然后用socket尝试连接,50表示延时时间,就是给它多少时间去建立连接,如果超出了还没连接上则报超时异常,那么就继续尝试连接下个服务端socket,直到遍历完这个网段内所有IP
for(int i=1;i<255;i++){
try {
Socket socket = new Socket();
InetSocketAddress s = new InetSocketAddress(resultIP+i, 30000);
socket.connect(s,50);
Message message = new Message();
message.what=1000;
message.obj=resultIP+i;
handler.sendMessage(message);
flag =true;
socket.close();
break;
} catch (IOException e) {
handler.sendEmptyMessage(i);
}
}如果所有IP都遍历完还没找到可连接的服务端,那么就跳到ReScanActivity

可以重新扫描也可以退出
一旦找到可连接服务端IP则跳到MainActivity,并会把可连接的IP传过来

在MainActivity中,就可以实现对PC的控制了。这里主要是3点。
1.当然是拿到ScanActivity传过来的IP,没有这个,什么都干不了
Intent intent = getIntent();
connIP = intent.getStringExtra("ip");2.获取用户点击的按钮并做相应的操作
@Override
public void onClick(View v) {
// 连接服务器
switch (v.getId()) {
case R.id.btnShutdown:
final String shutdown = "shutdown";
if(connThread!=null){
connThread.interrupt();
}
connThread = new ConnThread(connIP,30000,shutdown);
connThread.start();
break;
case R.id.btnReboot:
final String restart = "restart";
if(connThread!=null){
connThread.interrupt();
}
connThread = new ConnThread(connIP,30000,restart);
connThread.start();
break;
case R.id.btnCancel:
final String cancel = "cancel";
if(connThread!=null){
connThread.interrupt();
}
connThread = new ConnThread(connIP,30000,cancel);
connThread.start();
break;
case R.id.btnClose:
finish();
break;
default:
break;
}
}3.开个子线程,在这里就要建立与服务端的连接了,并将操作信息发送给服务端,在服务端会做判断
@Override
public void run() {
try {
client_socket = new Socket(ip, port);
while(true){
data_output = new DataOutputStream(client_socket.getOutputStream());
data_input = new DataInputStream(client_socket.getInputStream());
String msg="";
if ((data_output != null) && (!content.equals(""))) {
data_output.writeUTF(content);
}
msg = data_input.readUTF();
System.out.println(msg);
if(msg!=null&&!"".equals(msg)){
Message message = new Message();
message.what=1;
message.obj=msg;
handler.sendMessage(message);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(data_output!=null){
data_output.close();
}
if(data_input!=null){
data_input.close();
}
if(client_socket!=null){
client_socket=null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
super.run();
}到这里就可以实现与android客户端对PC的关机,重启等操作了。
有几点需要注意的:
1.android模拟器启动应用会报错,用真机测试
2.有时会出现,明明开了服务端,但是客户端扫描不到,原因可能是网络阻塞,可以把扫描时的延时时间调大点,但这样也就增加了扫描耗时
服务端代码拷过去就能用
客户端代码点这里
http://download.csdn.net/detail/beautiful_life12/8783463
客户端app
http://download.csdn.net/detail/beautiful_life12/8783493
