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。
网络通讯。就这么简单。
来源: http://www.bubuko.com/infodetail-2045663.html