標籤:break 貨幣 ons over block home rip 地址 name
1、為了開發“天地幣”這個Android手機項目,須要用到Socket編程。
2、天地幣是一種類似於比特幣的虛擬貨幣。
3、為了賺取CSDN的C幣,須要寫篇部落格。
4、乾脆將調試Socket的項目發出來跟網友分享。
閑話休提,直接上代碼,首先是字串的定義:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="app_name">xyzSocket</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> <string name="ipaddr_str">本機IP:</string> <string name="serveripaddr_str">伺服器IP:</string> <string name="server_str">設定為服務端</string> <string name="client_str">串連為用戶端</string> <string name="mymachine_str">本機就是</string> <string name="send_str">發送</string> <string name="online_str">0線上</string> <string name="threeline_str">第1行\n第2行\n第3行\n</string> </resources>
其次是xml檔案:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.xyzsocket.MainActivity$PlaceholderFragment" > <RelativeLayout android:id="@+id/relativelayout_1" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/ipaddr_label_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="@string/ipaddr_str" /> <EditText android:id="@+id/myipaddr_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/ipaddr_label_1" android:layout_toLeftOf="@+id/noline_label_1" /> <TextView android:id="@+id/online_label_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="@string/online_str" /> </RelativeLayout> <RelativeLayout android:id="@+id/relativelayout_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/relativelayout_1" > <EditText android:id="@+id/server_receiver" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="3" android:text="@string/threeline_str" /> </RelativeLayout> <RelativeLayout android:id="@+id/relativelayout_3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/relativelayout_2" > <TextView android:id="@+id/ipaddr_label_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="@string/serveripaddr_str" /> <EditText android:id="@+id/serveripaddr_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/ipaddr_label_2" android:layout_toLeftOf="@+id/serveripaddr_check" /> <CheckBox android:id="@+id/serveripaddr_check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="@string/mymachine_str" /> </RelativeLayout> <RelativeLayout android:id="@+id/relativelayout_4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/relativelayout_3" > <EditText android:id="@+id/send_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/butt_send" /> <Button android:id="@+id/butt_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="@string/send_str" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:orientation="horizontal" android:layout_below="@+id/send_message" > <Button android:id="@+id/butt_server" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_str" android:layout_below="@+id/send_message" /> <Button android:id="@+id/butt_client" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/client_str" android:layout_below="@+id/send_message" /> </LinearLayout> </RelativeLayout> </RelativeLayout>
最基本的是代碼:
package com.example.xyzsocket;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.UnknownHostException;import java.util.ArrayList;import android.support.v7.app.ActionBarActivity;import android.support.v7.app.ActionBar;import android.support.v4.app.Fragment;import android.content.Context;import android.net.wifi.WifiInfo;import android.net.wifi.WifiManager;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.EditText;import android.widget.TextView;import android.os.Build;public class MainActivity extends ActionBarActivity {private EditText et01 = null;private EditText et02 = null;private EditText et03 = null;private EditText et04 = null;private Button bn01 = null;private Button bn02 = null;private Button bn03 = null;private CheckBox cb01 = null;private TextView tv01 = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (savedInstanceState == null) {getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();}}private String intToIp(int i){return (i & 0xFF) + "." + ((i>>8) & 0xFF) + "." + ((i>>16) & 0xFF) + "." + ((i>>24) & 0xFF);}@Overridepublic void onWindowFocusChanged(boolean hasFocus) {// TODO Auto-generated method stubsuper.onWindowFocusChanged(hasFocus);if( et01 == null ){et01 = (EditText) findViewById(R.id.myipaddr_edit);if(et01 != null){WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);if(!wifiManager.isWifiEnabled()){wifiManager.setWifiEnabled(true);}WifiInfo wifiInfo = wifiManager.getConnectionInfo();int ipAddress = wifiInfo.getIpAddress();et01.setText(intToIp(ipAddress));}}if( et02 == null ){et02 = (EditText) findViewById(R.id.server_receiver);if(et02 != null){}}if( et03 == null ){et03 = (EditText) findViewById(R.id.serveripaddr_edit);if(et03 != null){}}if( et04 == null ){et04 = (EditText) findViewById(R.id.send_message);if(et04 != null){et04.setEnabled(false);}}if( bn01 == null ){bn01 = (Button) findViewById(R.id.butt_server);if( bn01 != null ){bn01.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub new Thread(){ @Override public void run() { //網路訪問的代碼放在這裡 server(); } }.start(); }});}}if( bn02 == null ){bn02 = (Button) findViewById(R.id.butt_client);if( bn02 != null ){bn02.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub new Thread(){ @Override public void run() { //網路訪問的代碼放在這裡 client(); } }.start(); }});}}if( bn03 == null ){bn03 = (Button) findViewById(R.id.butt_send);if( bn03 != null ){bn03.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub new Thread(){ @Override public void run() { //網路訪問的代碼放在這裡 sendmsg(); } }.start(); }});bn03.setEnabled(false);}}if( cb01 == null ){cb01 = (CheckBox) findViewById(R.id.serveripaddr_check);if( cb01 != null ){cb01.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// TODO Auto-generated method stubMessage msg = new Message();msg.arg1 = isChecked?1:0;msg.what = 103;handler.sendMessage(msg);}});}}if( tv01 == null ){tv01 = (TextView) findViewById(R.id.online_label_1);if( tv01 != null ){}}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}/** * A placeholder fragment containing a simple view. */public static class PlaceholderFragment extends Fragment {public PlaceholderFragment() {}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.fragment_main, container,false);return rootView;}}private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);myHandleMessage(msg);}};private void myHandleMessage(Message msg){switch(msg.what){case 101:bn01.setText("伺服器中止");break;case 102: bn01.setText(getString(R.string.server_str));break;case 103:if(msg.arg1>0){et03.setText(et01.getText().toString());}break;case 104:bn02.setText(msg.arg1>0?"用戶端中止":getString(R.string.client_str));bn03.setEnabled(msg.arg1>0);et04.setEnabled(msg.arg1>0);break;case 110:String str = et02.getText().toString();int i = str.indexOf("\n");if(i>0){str = str.substring(i+1);}str += (String)msg.obj;str += "\n";et02.setText(str);break;case 111:Log.i("DEBUG", "用戶端收到:" + (String)msg.obj);break;case 112:Log.i("DEBUG", "伺服器中止了!!");tv01.setText("" + list.size() + "線上");bn02.setText(getString(R.string.client_str));bn03.setEnabled(false);et04.setEnabled(false);break;case 113:Log.i("DEBUG", "用戶端退出了!!");tv01.setText("" + list.size() + "線上");break;case 114:tv01.setText("" + list.size() + "線上");break;}} ServerSocket aServerSocket = null; ArrayList list = new ArrayList(); private void server(){myServerThread thread;if( aServerSocket != null ){try{aServerSocket.close();aServerSocket = null;}catch(IOException e){e.printStackTrace();} if( bn01 != null ) { Message msg = new Message(); msg.what = 102; handler.sendMessage(msg); }return;} try { aServerSocket = new ServerSocket(55555); Log.i("DEBUG", "already listen 55555 port."); } catch (Exception e) { e.printStackTrace(); } if(aServerSocket == null){ Log.i("DEBUG", "偵聽失敗了!!"); return; } Log.i("DEBUG", "偵聽成功了!!"); if( bn01 != null ) { Message msg = new Message(); msg.what = 101; handler.sendMessage(msg); } int num = 0; while (num < 10) { Socket aSessionSoket = null; try { Log.i("DEBUG", "偵聽前!!"); aSessionSoket = aServerSocket.accept(); Log.i("DEBUG", "偵聽後!!"); thread = new myServerThread(aSessionSoket); thread.start(); Message msg = new Message(); msg.what = 114; handler.sendMessage(msg); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); Log.i("DEBUG", "伺服器手動中止了!!"); for(int i=0;i<list.size();i++){ Socket s = (Socket)list.get(i); try{ s.close(); }catch(IOException e){ e.printStackTrace(); } } list.clear(); break; } num = list.size(); Log.i("DEBUG", "socket count = " + num); }} class myServerThread extends Thread { public Socket aSessionSoket = null; public myServerThread(Socket socket) { aSessionSoket = socket; list.add(socket); } public void run() { DataInputStream aDataInput = null; DataOutputStream aDataOutput = null; try { aDataInput = new DataInputStream(aSessionSoket.getInputStream()); aDataOutput = new DataOutputStream(aSessionSoket.getOutputStream()); while (true) { Log.i("DEBUG", "伺服器接收前!!");String str = aDataInput.readUTF(); // read msg. Log.i("DEBUG", "伺服器接收後!!");Message msg = new Message();msg.obj = str;msg.what = 110;handler.sendMessage(msg);aDataOutput.writeUTF("OK:" + str);} } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();} finally { try {if (aDataInput != null)aDataInput.close();if (aDataOutput != null) aDataOutput.close(); list.remove(aSessionSoket); aSessionSoket.close();// 這裡的退出是用戶端主動斷開Message msg = new Message();msg.what = 113;handler.sendMessage(msg);} catch (Exception e2) { e2.printStackTrace(); } } } }Socket clientsocket = null;private void client(){Message msg;if( clientsocket != null ){try{clientsocket.close();clientsocket = null;}catch(IOException e){e.printStackTrace();return;} msg = new Message(); msg.what = 104; msg.arg1 = 0; handler.sendMessage(msg);return;}InetAddress serverAddr;try {serverAddr = InetAddress.getByName ( et03.getText().toString() );Log.d ( "DEBUG" , "C: Connecting..." );// 與伺服器擷取串連clientsocket = new Socket(serverAddr, 55555);} catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace();} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();}if(clientsocket == null){ Log.i("DEBUG", "串連失敗了!!");return;} if( bn03 != null ) { msg = new Message(); msg.what = 104; msg.arg1 = 1; handler.sendMessage(msg); }myClientThread thread = new myClientThread(clientsocket); thread.start(); } class myClientThread extends Thread { public Socket aSessionSoket = null; public myClientThread(Socket socket) { aSessionSoket = socket; } public void run() { DataInputStream aDataInput = null; try { aDataInput = new DataInputStream(aSessionSoket.getInputStream()); while (true) { Log.i("DEBUG", "用戶端接收前!!");String str = aDataInput.readUTF(); Log.i("DEBUG", "用戶端接收後!!");Message msg = new Message();msg.obj = str;msg.what = 111;handler.sendMessage(msg);} } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace();Message msg = new Message();msg.what = 112;handler.sendMessage(msg);} finally { try {if (aDataInput != null)aDataInput.close();aSessionSoket.close();} catch (Exception e2) { e2.printStackTrace(); } } } }private void sendmsg(){ DataOutputStream aDataOutput = null; String message = et04.getText().toString(); if(message.isEmpty()){ return; }try {Log.i ( "DEBUG" , "C: Sending: ‘" + message + "‘" );aDataOutput = new DataOutputStream(clientsocket.getOutputStream());aDataOutput.writeUTF(message);} catch (Exception e) {e.printStackTrace();} finally {}}}
別忘了加入許可權:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission><uses-permission android:name="android.permission.INTERNET"></uses-permission>
最後簡單說說使用方法:
1、軟體自己主動檢測到自己wifi的IP地址。
2、一台機器能夠同一時候扮演server和client。
3、其它機器能夠登入到同一台server。
網路通訊。就這麼簡單。
天地幣:所用到的 Android Socket 通訊編程技術實驗