天地币:所用到的 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。

网络通讯。就这么简单。

				
时间: 2024-08-24 01:28:40

天地币:所用到的 Android Socket 通讯编程技术试验的相关文章

Protobuf实现Android Socket通讯开发教程

本节为您介绍Protobuf实现Android Socket通讯开发教程,因此,我们需要先了理一下protobuf 是什么? Protocol buffers是一种编码方法构造的一种有效而可扩展的格式的数据. 谷歌使用其内部几乎RPC协议和文件格式的所有协议缓冲区. protobuf 适用的语言 正宗(Google 自己内部用的)的protobuf支持三种语言:Java .c++和Pyton,很遗憾的是并不支持.Net 或者 Lua 等语言,但社区的力量是不容忽视的,由于protobuf确实比J

android socket 通讯(客户端) 发送数据

/** ClientSocket通讯类 **/ public class ClientSocket  { /**服务器地址*/ private String serverUrl="192.168.124.214"; /**服务器端口*/ private int serverPort=8888; /*发送命令线程*/ class sendCommandThread extends Thread{ private String command; public sendCommandThre

初识Socket通讯编程(一)

一.什么是socket? 当两台计算机需要通信的时候,往往我们使用的都是TCP去实现的,但是并不会直接去操作TCP协议,通常是通过Socket进行tcp通信.Socket是操作系统提供给开发者的一个接口,通过它,就可以实现设备之间的通信. 二.TCP是如何通信的? TCP连接和断开分别会存在3次握手/4此握手的过程,并且在此过程中包含了发送数据的长度(接受数据的长度),无容置疑,这个过程是复杂的,这里我们不需要做深入的探讨.如果有兴趣,可以参考此文章,这里详细的解释了TCP通信的过程: http

android 蓝牙通讯编程 备忘

1.启动App后: 判断->蓝牙是否打开(所有功能必须在打牙打开的情况下才能用) 已打开: 启动代码中的蓝牙通讯Service 未打开: 发布 打开蓝牙意图(系统),根据Activity返回进场操作 打开成功,启动代码中的蓝牙通讯Service 用户点back或失败 退出App 2.蓝牙设备列表: 2.1显示已经配对列表: 注册蓝牙设备发现广播 广播中将发现的设备添加到列表2.2当用户点Scan时,启动蓝牙发现,发现设备时会收到广播事件. 2.3用户点某个条目时,将改条目的 MAC返回给主Act

Android笔记之adb命令应用实例1(手机端与PC端socket通讯下)

由于本人学习Android也挺长时间了,一直把日记记在evernote里面,由于刚离职比较空闲就打算把evernote里的日志一遍遍整理出来发布到网上分享. 本篇将分别使用C#和java语言,来实现和android端通讯的PC客户端代码. 通过adb和Android通讯需要引用adb相关的组件到项目中,分别为:adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll. 可以在XXX\sdk\platform-tools目录下找到 首先看C#语言的实现: 界面效果如下: nam

Android笔记之adb命令应用实例1(手机端与PC端socket通讯上)

由于本人学习Android也挺长时间了,一直把日记记在evernote里面,由于刚离职比较空闲就打算把evernote里的日志一遍遍整理出来发布到网上分享. Android端的代码: 布局文件:activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools&quo

Android网络通讯简介

网络通信应该包含三部分的内容:发送方.接收方.协议栈.发送方和接收方是参与通信的主体,协议栈是发送方和接收方进行通信的契约.按照服务类型,网络通信可分为面向连接和无连接的方式.面向连接是在通信前建立通信链路,而通信结束后释放该链路.无连接的方式则不需要在通信前建立通信连接,这种方式不保证传输的质量. Android提供了多种网络通信的方式,如Java中提供的网络编程,在Android中都提供了支持.Android中常用的网络编程方式如下: 针对TCP/IP协议的Socket和ServerSock

客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)

今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些不同的想法. 首先,个人职业发展是否成功, 技术只是其中一小块,尤其是在大公司, 更多的是依靠所谓的软实力.作为一个对技术有追求的工匠,我们下面重点说技术相关的. 现在回头看计算机行业的发展,我们看到不同的发展阶段: 1. PC时代,这个时代离我们并不遥远, 也有是2000年前后, 该时代最鲜明的特征是Win

Android Socket编程学习笔记

通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务. 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定. 在java中,Socke