首页 > 代码库 > 天地币:所用到的 Android Socket 通讯编程技术试验
天地币:所用到的 Android Socket 通讯编程技术试验
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; @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 通讯编程技术试验