前言:
在这里强调局域网,是因为内网之间的设备通信时,无需经过外网,若想内网的设备能够与外网进行通信,可自行百度其解决办法...
虽说利用wifi,实质是怎么利用socket来进行通信的问题
步骤一:编写服务端和客户端的代码
服务端代码(MainActivity.java):
package com.example.dai.wifiserver; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.widget.EditText; import android.widget.TextView; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class MainActivity extends AppCompatActivity { private TextView editText_1; private EditText editText_2; private ServerSocket serverSocket = null; StringBuffer stringBuffer = new StringBuffer(); private InputStream inputStream; public Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case 1: editText_1.setText(msg.obj.toString()); break; case 2: editText_2.setText(msg.obj.toString()); stringBuffer.setLength(0); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText_1 = (TextView) findViewById(R.id.et_1); editText_2 = (EditText) findViewById(R.id.et_2); receiveData(); } /* 服务器端接收数据 需要注意以下一点: 服务器端应该是多线程的,因为一个服务器可能会有多个客户端连接在服务器上; */ public void receiveData(){ Thread thread = new Thread(){ @Override public void run() { super.run(); /*指明服务器端的端口号*/ try { serverSocket = new ServerSocket(8000); } catch (IOException e) { e.printStackTrace(); } GetIpAddress.getLocalIpAddress(serverSocket); Message message_1 = handler.obtainMessage(); message_1.what = 1; message_1.obj = "IP:" + GetIpAddress.getIP() + " PORT: " + GetIpAddress.getPort(); handler.sendMessage(message_1); while (true){ Socket socket = null; try { socket = serverSocket.accept(); inputStream = socket.getInputStream(); } catch (IOException e) { e.printStackTrace(); } new ServerThread(socket,inputStream).start(); } } }; thread.start(); } class ServerThread extends Thread{ private Socket socket; private InputStream inputStream; private StringBuffer stringBuffer = MainActivity.this.stringBuffer; public ServerThread(Socket socket,InputStream inputStream){ this.socket = socket; this.inputStream = inputStream; } @Override public void run() { int len; byte[] bytes = new byte[20]; boolean isString = false; try { //在这里需要明白一下什么时候其会等于 -1,其在输入流关闭时才会等于 -1, //并不是数据读完了,再去读才会等于-1,数据读完了,最结果也就是读不到数据为0而已; while ((len = inputStream.read(bytes)) != -1) { for(int i=0; i<len; i++){ if(bytes[i] != '\0'){ stringBuffer.append((char)bytes[i]); }else { isString = true; break; } } if(isString){ Message message_2 = handler.obtainMessage(); message_2.what = 2; message_2.obj = stringBuffer; handler.sendMessage(message_2); isString = false; } } //当这个异常发生时,说明客户端那边的连接已经断开 } catch (IOException e) { e.printStackTrace(); try { inputStream.close(); socket.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } /*当按返回键时,关闭相应的socket资源*/ @Override public void onBackPressed() { super.onBackPressed(); try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
GetIpAddress.java:
package com.example.dai.wifiserver; import android.util.Log; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.ServerSocket; import java.net.SocketException; import java.util.Enumeration; public class GetIpAddress { public static String IP; public static int PORT; public static String getIP(){ return IP; } public static int getPort(){ return PORT; } public static void getLocalIpAddress(ServerSocket serverSocket){ try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();){ NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();){ InetAddress inetAddress = enumIpAddr.nextElement(); String mIP = inetAddress.getHostAddress().substring(0, 3); if(mIP.equals("192")){ IP = inetAddress.getHostAddress(); //获取本地IP PORT = serverSocket.getLocalPort(); //获取本地的PORT Log.e("IP",""+IP); Log.e("PORT",""+PORT); } } } } catch (SocketException e) { e.printStackTrace(); } } }
客户端代码:
package com.example.dai.wificlient; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.EditText; import android.widget.Toast; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class MainActivity extends AppCompatActivity { private EditText editText_ip,editText_data; private OutputStream outputStream = null; private Socket socket = null; private String ip; private String data; private boolean socketStatus = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); editText_ip = (EditText) findViewById(R.id.et_ip); editText_data = (EditText) findViewById(R.id.et_data); } public void connect(View view){ ip = editText_ip.getText().toString(); if(ip == null){ Toast.makeText(MainActivity.this,"please input Server IP",Toast.LENGTH_SHORT).show(); } Thread thread = new Thread(){ @Override public void run() { super.run(); if (!socketStatus) { try { socket = new Socket(ip,8000); if(socket == null){ }else { socketStatus = true; } outputStream = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } } } }; thread.start(); } public void send(View view){ data = editText_data.getText().toString(); if(data == null){ Toast.makeText(MainActivity.this,"please input Sending Data",Toast.LENGTH_SHORT).show(); }else { //在后面加上 '\0' ,是为了在服务端方便我们去解析; data = data + '\0'; } Thread thread = new Thread(){ @Override public void run() { super.run(); if(socketStatus){ try { outputStream.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } } }; thread.start(); } /*当客户端界面返回时,关闭相应的socket资源*/ @Override public void onBackPressed() { super.onBackPressed(); /*关闭相应的资源*/ try { outputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
步骤二:
将服务端app下载至其中一台android设备,将客户端下载至另一台android设备,然后先开启服务端程序,最后再开启客户端程序
测试效果图如下:
服务端:
客户端:
服务端源码:
客户端源码:
关注微信公众号获取更多资讯