基於TCP的安卓服務器開發

一.說明

前文介紹了基於安卓客戶端的開發,在此基礎上,進行少量改動便可開發出一款基於TCP的安卓服務器,理論知識請參見筆者上一篇博文,下面直接實踐操做。java

二.權限申明

 1     <!--容許應用程序改變網絡狀態-->
 2     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
 3 
 4     <!--容許應用程序改變WIFI鏈接狀態-->
 5     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
 6 
 7     
 8     <!--容許應用程序訪問有關的網絡信息-->
 9     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
10 
11     <!--容許應用程序訪問WIFI網卡的網絡信息-->
12     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
13 
14     <!--容許應用程序徹底使用網絡-->
15     <uses-permission android:name="android.permission.INTERNET"/>

三.佈局文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical" android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5     <LinearLayout
 6         android:layout_width="match_parent"
 7         android:layout_height="wrap_content"
 8         android:layout_marginLeft="10dp"
 9         android:layout_marginRight="10dp"
10         android:layout_marginTop="10dp"
11         android:layout_marginBottom="10dp">
12     <TextView
13         android:id="@+id/LocalIPTextView"
14         android:layout_width="match_parent"
15         android:layout_height="wrap_content"
16         android:hint="本機IP:"
17         android:textSize="25dp"/>
18     </LinearLayout>
19     <LinearLayout
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"
22         android:layout_marginLeft="10dp"
23         android:layout_marginRight="10dp"
24         android:layout_marginBottom="10dp">
25         >
26         <EditText
27             android:id="@+id/MessagetoSendEditText"
28             android:layout_width="0dp"
29             android:layout_height="match_parent"
30             android:layout_weight="3"
31             android:text="Data from Server"/>
32         <Button
33             android:id="@+id/SendButton"
34             android:layout_width="0dp"
35             android:layout_height="wrap_content"
36             android:layout_weight="1"
37             android:text="發送"/>
38     </LinearLayout>
39 
40     <LinearLayout
41         android:layout_width="match_parent"
42         android:layout_height="wrap_content"
43         android:layout_marginLeft="10dp"
44         android:layout_marginRight="10dp"
45 
46         android:layout_marginBottom="10dp">
47         <TextView
48             android:id="@+id/DisplayTextView"
49             android:layout_width="match_parent"
50             android:layout_height="wrap_content"
51             android:textSize="25dp"/>
52     </LinearLayout>
53 
54 
55 </LinearLayout>

 

四.具體實現代碼

  1 package com.example.john.androidsockettest;
  2 
  3 import android.content.Context;
  4 import android.net.ConnectivityManager;
  5 import android.net.NetworkInfo;
  6 import android.net.wifi.WifiInfo;
  7 import android.net.wifi.WifiManager;
  8 import android.os.Handler;
  9 import android.os.Message;
 10 import android.support.v7.app.AppCompatActivity;
 11 import android.os.Bundle;
 12 import android.view.View;
 13 import android.widget.Button;
 14 import android.widget.EditText;
 15 import android.widget.TextView;
 16 
 17 import java.io.BufferedReader;
 18 import java.io.IOException;
 19 import java.io.InputStreamReader;
 20 import java.io.OutputStream;
 21 import java.net.Inet4Address;
 22 import java.net.InetAddress;
 23 import java.net.NetworkInterface;
 24 import java.net.ServerSocket;
 25 import java.net.Socket;
 26 import java.net.SocketException;
 27 import java.util.Enumeration;
 28 
 29 public class MainActivity extends AppCompatActivity {
 30 
 31     //線程及套接字定義
 32     public Socket socket = null;
 33     public ServerSocket serverSocket = null;
 34     private AcceptThread acceptThread = null;
 35     private ReceiveThread receiveThread = null;
 36     private SendThread sendThread = null;
 37     //Handler中的消息類型
 38     public static final int DEBUG = 0x00;
 39     public static final int RECEIVEDATAFROMCLIENT = 0x01;
 40     public static final int SENDDATATOCLIENT = 0x02;
 41     //控件
 42     private TextView localIPTextView;
 43     private EditText messagetoSendEditText;
 44     private Button sendButton;
 45     private TextView displayTextView;
 46     //變量定義
 47     String messagetoSend="";
 48 
 49     public Handler myHandler = new Handler() {
 50         @Override
 51         public void handleMessage(Message msg) {
 52             if (msg.what == RECEIVEDATAFROMCLIENT) {
 53                 Bundle bundle = msg.getData();
 54                 displayTextView.append("Client:"+bundle.getString("string1")+"\n");
 55             }
 56             else if (msg.what == DEBUG) {
 57                 Bundle bundle = msg.getData();
 58                 displayTextView.append("Debug:"+bundle.getString("string1")+"\n");
 59             }
 60             else if (msg.what == SENDDATATOCLIENT) {
 61                 Bundle bundle = msg.getData();
 62                 displayTextView.append("Server:"+bundle.getString("string1")+"\n");
 63             }
 64         }
 65 
 66     };
 67     //子線程更新UI
 68     public void SendMessagetoHandler(final int messageType , String string1toHandler){
 69         Message msg = new Message();
 70         msg.what = messageType;    //消息類型
 71         Bundle bundle = new Bundle();
 72         bundle.clear();
 73         bundle.putString("string1", string1toHandler); //向bundle中添加字符串
 74         msg.setData(bundle);
 75         myHandler.sendMessage(msg);
 76     }
 77     @Override
 78     protected void onCreate(Bundle savedInstanceState) {
 79         super.onCreate(savedInstanceState);
 80         setContentView(R.layout.activity_main);
 81         //控件對象獲取
 82         localIPTextView = (TextView)findViewById(R.id.LocalIPTextView);
 83         messagetoSendEditText = (EditText)findViewById(R.id.MessagetoSendEditText);
 84         sendButton = (Button)findViewById(R.id.SendButton);
 85         displayTextView = (TextView)findViewById(R.id.DisplayTextView);
 86         //服務器IP獲取顯示
 87         localIPTextView.setText("本機IP:"+getIPAddress(this));
 88         //開啓接受線程
 89         acceptThread = new AcceptThread();
 90         acceptThread.start();
 91         sendButton.setOnClickListener(new View.OnClickListener() {
 92 
 93         @Override
 94         public void onClick(View v) {
 95             messagetoSend = messagetoSendEditText.getText().toString();
 96             //使用鏈接成功後獲得的socket構造發送線程,每點擊一次send按鈕觸發一次發送線程
 97             sendThread = new SendThread(socket);
 98             sendThread.start();
 99         }
100     });
101 
102     }
103     //*****  接受線程  *****
104     class AcceptThread extends Thread{
105         @Override
106         public void run() {
107             try{
108                 serverSocket = new ServerSocket(8086);
109                 socket = serverSocket.accept();
110             }catch (IOException e){
111                 e.printStackTrace();
112             }
113             SendMessagetoHandler(DEBUG,"客戶端鏈接成功!");
114             //構造並開啓接收線程
115             receiveThread = new ReceiveThread(socket);
116             receiveThread.start();
117         }
118     }
119     //********  接收線程  **********
120     class ReceiveThread extends Thread{
121 
122         private Socket mSocket;
123         //接收線程的構造函數,由接受線程傳入套接字
124         public ReceiveThread(Socket socket){mSocket = socket;}
125         @Override
126         public void run() {
127             while(true){               //鏈接成功後將一直運行
128                 try {
129                     BufferedReader bufferedReader;
130                     String line = null;
131                     String readBuffer="";
132                     bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
133 
134                     while ((line = bufferedReader.readLine()) != null) {
135                         readBuffer = line + readBuffer;
136                         SendMessagetoHandler(RECEIVEDATAFROMCLIENT,readBuffer);
137                         readBuffer = "";
138                     }
139 
140                 }catch (IOException e) {
141                     e.printStackTrace();
142                     //更新UI:顯示發送錯誤信息
143                     SendMessagetoHandler(DEBUG,"接收失敗!");
144                     return;
145                 }
146             }
147         }
148     }
149     //********  發送線程  **********
150     class SendThread extends Thread{
151         private Socket mSocket;
152         //發送線程的構造函數,由接受線程傳入套接字
153         public SendThread(Socket socket) {mSocket = socket;}
154 
155         @Override
156         public void run() {
157             try{
158                 OutputStream outputStream = mSocket.getOutputStream();
159                 //向服務器發送信息
160                 outputStream.write(messagetoSend.getBytes("gbk"));
161                 outputStream.flush();
162                 //更新UI:顯示發送出的數據
163                 SendMessagetoHandler(SENDDATATOCLIENT,messagetoSend);
164             }catch (IOException e) {
165                 e.printStackTrace();
166                 //更新UI:顯示發送錯誤信息
167                 SendMessagetoHandler(DEBUG,"發送失敗!");
168                 return;
169             }
170         }
171     }
172     //*****  獲取本機的ip地址
173     private String getlocalip(){
174         WifiManager wifiManager = (WifiManager)this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
175         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
176         int ipAddress = wifiInfo.getIpAddress();
177         //  Log.d(Tag, "int ip "+ipAddress);
178         if(ipAddress==0)return null;
179         return ((ipAddress & 0xff)+"."+(ipAddress>>8 & 0xff)+"."
180                 +(ipAddress>>16 & 0xff)+"."+(ipAddress>>24 & 0xff));
181     }
182 
183     public static String getIPAddress(Context context) {
184         NetworkInfo info = ((ConnectivityManager) context
185                 .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
186         if (info != null && info.isConnected()) {
187             if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//當前使用2G/3G/4G網絡
188                 try {
189                     //Enumeration<NetworkInterface> en=NetworkInterface.getNetworkInterfaces();
190                     for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
191                         NetworkInterface intf = en.nextElement();
192                         for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
193                             InetAddress inetAddress = enumIpAddr.nextElement();
194                             if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
195                                 return inetAddress.getHostAddress();
196                             }
197                         }
198                     }
199                 } catch (SocketException e) {
200                     e.printStackTrace();
201                 }
202 
203             } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//當前使用無線網絡
204                 WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
205                 WifiInfo wifiInfo = wifiManager.getConnectionInfo();
206                 int ipAddress = wifiInfo.getIpAddress();//獲得IPV4地址
207                 return ((ipAddress & 0xff)+"."+(ipAddress>>8 & 0xff)+"."  //將獲得的int類型的IP轉換爲String類型
208                         +(ipAddress>>16 & 0xff)+"."+(ipAddress>>24 & 0xff));
209             }
210         } else {
211             //當前無網絡鏈接,請在設置中打開網絡
212         }
213         return null;
214     }
215 }  

 

 

五.Debug

 

 

六.實際運行效果

 

若是這篇blog對您有所幫助,請留下您的一個贊,也歡迎留言討論,筆者將在第一時間回覆!android

相關文章
相關標籤/搜索