Android客戶端與java伺服器端的Socket連線
阿新 • • 發佈:2019-03-21
1.首先直接看伺服器端程式碼:
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(); } } }
2、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>
3、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(); } } } }
4、在清單檔案中增加兩條授權:(重要)
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_N