天地币(所用到的 Android Socket 通讯编程技术试验)

高斋晓开卷,独共圣人语。这篇文章主要讲述天地币:所用到的 Android Socket 通讯编程技术试验相关的知识,希望能为你提供帮助。
1、为了开发“天地币”这个android手机项目,须要用到Socket编程。
2、天地币是一种类似于比特币的虚拟货币。


3、为了赚取CSDN的C币,须要写篇博客。
4、干脆将调试Socket的项目发出来跟网友分享。

天地币(所用到的 Android 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; @Override protected 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); } @Override public void onWindowFocusChanged(boolean hasFocus) { // TODO Auto-generated method stub super.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() {@Override public 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() {@Override public 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() {@Override public 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() {@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // TODO Auto-generated method stub Message 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 ){} } } @Override public 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; } @Override public 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() { }@Override public 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(){@Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.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 通讯编程技术试验)】














    推荐阅读