服务器端代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.LineNumberReader;
public class Server extends Thread {
private ServerSocket server = null;
private static final int PORT = 6000;
private BufferedWriter writer;
private BufferedReader reader;
private Server() throws IOException {
// 创建Socket服务器
CreateSocket();
}
public void run() {
Socket client;
String txt;
try {
// 线程无限循环,实时监听socket端口
while (true){
client = ResponseSocket();
// 响应客户端链接请求。。
while (true) {
txt = ReceiveMsg(client);
// 链接获得客户端发来的命令
System.out.println(txt);
if (txt != null) {
// 执行命令
txt = exceCommand(txt);
}
// 向客户端返回消息
SendMsg(client, txt);
// 中断,关闭此次连接
break;
}
CloseSocket(client);
}
} catch (IOException e) {
System.out.println(e);
}
}
//创建一个ServerSocket实例,绑定到一个特定的端口。一个服务器端口最多可以支持50个链接,超出了则拒绝链接。
//所以,最多只能有50个客户端同时使用这个指定的端口向服务器发送消息
private void CreateSocket() throws IOException {
server = new ServerSocket(PORT);
System.out.println("Server starting..");
}
/*
ServerSocket:这个类是实现了一个服务器端的Socket,利用这个类可以监听来自网络的请求。
1、创建ServerSocket的方法:
ServerSocket(Int localPort)
ServerSocket(int localport,int queueLimit)
ServerSocket(int localport,int queueLimit,InetAddress localAddr)
创建一个ServerSocket必须指定一个端口,以便客户端能够向该端口号发送连接请求。端口的有效范围是0-65535
2、ServerSocket操作
Socket accept()
void close
accept()方法为下一个传入的连接请求创建Socket实例,并将已成功连接的Socket实例返回给服务器套接字,如果没有连接请求,
accept()方法将阻塞等待;
close方法用于关闭套接字
*/
private Socket ResponseSocket() throws IOException {
Socket client = server.accept();
System.out.println("client connected..");
return client;
}
//关闭socket
private void CloseSocket(Socket socket) throws IOException {
reader.close();
writer.close();
socket.close();
System.out.println("client closed..");
}
//向客户端发送消息
private void SendMsg(Socket socket, String Msg) throws IOException {
writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
writer.write(Msg + "\n");
writer.flush();
}
//接收来自客户端的消息。服务器通过server.accept();接收来自客户端的套接字,采用I/O方式
//将套接字的消息取出来
private String ReceiveMsg(Socket socket) throws IOException {
reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
System.out.println("server get input from client socket..");
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
return line;
}
return line;
}
//执行客户端发送来的命令。服务器将在本机执行客户端发送过来的消息(命令)。
//并返回执行命令后,服务器返回的结果。譬如,在linux下执行“ls”命令,返回的是当前目录
//下面的所有文件的名称
private String exceCommand(String command) {
String msg = "";
try {
//Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()
//方法指示Java虚拟机创建一个子进程执行指定的可执行程序(命令),并返回与该子进程对应的Process对象实例。
//通过Process可以控制该子进程的执行或获取该子进程的信息
Process process = Runtime.getRuntime().exec(command);
InputStreamReader ir = new InputStreamReader(
process.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
msg += line + "\n";
}
} catch (java.io.IOException e) {
System.err.println("IOException " + e.getMessage());
}
return msg;
}
public static void main(final String args[]) throws IOException {
Server commandServer = new Server();
if (commandServer != null) {
// commandServer.stop();
commandServer.start();
}
}
}
Android客户端activity_main.xml代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/edittext"
android:hint="请输入内容"
/>
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"
></Button>
</LinearLayout>
Android客户端Activity.java代码:
package com.example.socket2;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
//服务器ip地址
public static final String DEFULT_PRES = "192.168.56.1";
public static final String PREFS_NAME = "PreferencesFile";
public static final int CONNENTED = 0;
public static final int UPDATALOG = 1;
private static final int PORT = 6000;
private EditText command;
private TextView log;
private Button send;
private String ip;
private String logMsg;
private Socket socket;
private BufferedWriter writer;
private InetSocketAddress isa = null;
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case CONNENTED:
logMsg += "Server Connented\n";
log.setText(logMsg);
break;
case UPDATALOG:
log.setText(logMsg);
log.setScrollContainer(true);
break;
}
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findviews();
init();
setonclick();
}
public void findviews() {
command = (EditText) this.findViewById(R.id.edittext);
log = (TextView) this.findViewById(R.id.textview);
send = (Button) this.findViewById(R.id.send);
}
private void init() {
log.setMovementMethod(ScrollingMovementMethod.getInstance());
logMsg = log.getText().toString();
//创建一个socket实例
socket = new Socket();
ip ="192.168.56.1" ;
}
private void setonclick() {
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ip = "192.168.56.1";
//当点击发送按钮时,开启一个tcpClient线程,向服务器发送消息
tcpClient tcp = new tcpClient(command.getText().toString());
tcp.start();
}
});
}
class tcpClient extends Thread {
String commandString;
public tcpClient() {
commandString = "ls";
}
public tcpClient(String command) {
commandString = command;
}
public void run() {
String recv;
try {
Socket ConSocket = new Socket();
//创建套接字地址,其中 IP 地址为通配符地址,端口号为指定值。
//有效端口值介于 0 和 65535 之间。端口号 zero 允许系统在 bind 操作中挑选暂时的端口。
isa = new InetSocketAddress(ip, PORT);
//建立一个远程链接
ConSocket.connect(isa);
//socket.connect(isa);
socket=ConSocket;
if (socket.isConnected()) {
Message msg = new Message();
msg.what = CONNENTED;
mHandler.sendMessage(msg);
}
//向服务器发送命令
writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
Log.i("msg", commandString.replace("\n", "")+"\n");
writer.write(commandString.replace("\n", "")+"\n");
writer.flush();
//等待,接收来自服务器返回的消息
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String line;
String txt = "";
while ((line = reader.readLine()) != null) {
txt += line + "\n";
}
reader.close();
recv = txt;
if (recv != null) {
logMsg += recv;
// close BufferedWriter and socket
writer.close();
socket.close();
// 将服务器返回的消息显示出来
Message msg = new Message();
msg.what = UPDATALOG;
mHandler.sendMessage(msg);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在清单文件中增加两条授权:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />