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。
网络通讯。就这么简单。