看了几天的Android WiFi通讯,总结一下,并附相关Demo(也是仿网上做的),建议收藏
两台设备(手机与手机,手机与硬件都一样)在同一WiFi下通讯,用的是TCP/IP协议,那我们应如何使用?其实很简单:
服务端:用ServerSocket开启一个端口(port),等待客户端连接,连接成功后可得到一个Socket,再用这个Socket就可以拿到服务端的输入流(InputStream)和输出流(OutputStream);
客户端:通过服务端的IP(在局域网下的IP)和Port(ServerSocket开启的端口号),用Socket进行连接,连接成功后当然就用这个Socket就可以拿到客户端的输入流(InputStream)和输出流(OutputStream)啦;
然后,服务端或客户端向输出流里写东西,另一端再从自己的输入流里读就完成了!~~
下面来看看具体实现
WiFi通讯需要申请的权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
在同一局域网下通讯
1.服务端
(1)启用一个服务端口
启用一个服务端口,并获得一个ServerSocket
mServerSocket = new ServerSocket(5000);//port:5000
(2)等待连接
定义一个用于等待客户端连接的线程
/**
* 连接线程
* 得到Socket
*/
class SocketAcceptThread extends Thread{
@Override
public void run() {
try {
//等待客户端进行连接,此时accept会阻塞,直到建立连接
mSocket = mServerSocket.accept();
} catch (IOException e) {
e.printStackTrace();
return;//accept error
}
//连接成功后,启动消息接收线程
startReader(mSocket);
}
}
//启动服务线程
SocketAcceptThread socketAcceptThread = new SocketAcceptThread();
socketAcceptThread.start();
(3)接收消息
定义一个线程来接收客户端发来的消息
private void startReader(final Socket socket) {
new Thread() {
@Override
public void run() {
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (true) {
// 读取数据
String msg = reader.readUTF();
Log.d(TAG, "客户端的信息:" + msg);
//告知客户端消息收到
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
writer.writeUTF("收到:" + msg); // 写一个UTF-8的信息
//向主线程发消息更新UI
Message message = new Message();
message.what = 1;
message.obj=msg;
handler.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
(4)关闭Socket
if (mServerSocket != null) {
try {
mServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(mSocket!=null){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
(5)获取服务端ip地址
public class NetWorkUtils {
/**
* 检查网络是否可用
*
* @param paramContext
* @return
*/
public static boolean checkEnable(Context paramContext) {
boolean i = false;
NetworkInfo localNetworkInfo = ((ConnectivityManager) paramContext
.getSystemService("connectivity")).getActiveNetworkInfo();
if ((localNetworkInfo != null) && (localNetworkInfo.isAvailable()))
return true;
return false;
}
/**
* 将ip的整数形式转换成ip形式
*
* @param ipInt
* @return
*/
public static String int2ip(int ipInt) {
StringBuilder sb = new StringBuilder();
sb.append(ipInt & 0xFF).append(".");
sb.append((ipInt >> 8) & 0xFF).append(".");
sb.append((ipInt >> 16) & 0xFF).append(".");
sb.append((ipInt >> 24) & 0xFF);
return sb.toString();
}
/**
* 获取当前ip地址
*
* @param context
* @return
*/
public static String getLocalIpAddress(Context context) {
try {
WifiManager wifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int i = wifiInfo.getIpAddress();
return int2ip(i);
} catch (Exception ex) {
return " 获取IP出错鸟!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();
}
// return null;
}
}
2.客户端
(1)进行连接
/**
* 连接线程
*/
class SocketConnectThread extends Thread{
public void run(){
try {
//指定ip地址和端口号
mSocket = new Socket(ipET.getText().toString(), 1989);
//获取输出流、输入流
// mOutStream = mSocket.getOutputStream();
// mInStream = mSocket.getInputStream();
} catch (Exception e) {
e.printStackTrace();
return;
}
startReader(mSocket);
}
}
socketConnectThread = new SocketConnectThread();
socketConnectThread.start();
(2)发送消息
/**
* 发送消息
* @param msg
*/
public void sendMessage(final String msg) {
if (msg.length() == 0){
return;
}
new Thread() {
@Override
public void run() {
try {
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
writer.writeUTF(msg); // 写一个UTF-8的信息
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
(3)接收消息
/**
* 接收消息
*/
private void startReader(final Socket socket) {
new Thread(){
@Override
public void run() {
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (true) {
// 读取数据
String msg = reader.readUTF();
Message message = new Message();
message.what = 1;
message.obj=msg;
handler.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
(4)关闭Socket
if(mSocket!=null){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}