1 Socket 简介

​ Socket(套接字)是应用层与 TCP/IP 协议通信的中间软件抽象层,它是一组接口,用户只需面向 Socket 编程,即可实现跨设备(网络)通讯。

​ Socket 是 java 里的东西,不是 Android 特有的,使用 Socket 需要导入的类如下。

java.net.ServerSocket
java.net.Socket

​ (1)服务端主要接口调用

// 获取 socket
mServerSocket = new ServerSocket(port)
// port 为端口号,取值:0~65535间的整数,前1024个端口号为固定端口,一般不提供给程序员使用,之后为注册端口,为避免端口冲突,建议 port 值取大点
mSocket = mServerSocket.accept() //调用此方法会阻塞线程,建议在子线程中执行 // 读取对端数据
in = mSocket.getInputStream()
byte[] bt = new byte[50]
in.read(bt) // 向对端发送数据
out = new PrintWriter(mSocket.getOutputStream())
out.print(content)
out.flush()

​ (2)客户端主要接口调用

// 获取 socket
mSocket = new Socket(ip, port) //调用此方法会阻塞线程,建议在子线程中执行
// ip 为服务端设备 ip 地址
// port 为端口号,取值:0~65535间的整数,前1024个端口号为固定端口,一般不提供给程序员使用,之后为注册端口,为避免端口冲突,建议 port 值取大点 // 读取对端数据
in = mSocket.getInputStream()
byte[] bt = new byte[50]
in.read(bt) // 向对端发送数据
out = new PrintWriter(mSocket.getOutputStream())
out.print(content)
out.flush()

​ 本文全部代码见→使用Socket实现跨设备通讯

2 项目结构

​ 注意:2个设备必须在局域网中(连同一个wifi )

3 服务端(socket_S)

​ Server.java

package com.zhyan8.socket_s;

import android.os.Handler;
import android.os.Message;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket; public class Server{
private ServerSocket mServerSocket;
private Socket mSocket;
private Handler mHandler;
private InputStream in;
private PrintWriter out;
private Object lock = new Object(); public Server(Handler handler, int port){
mHandler = handler;
try {
mServerSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
} public void connect() {
new Thread() {
@Override
public void run() {
try {
synchronized (lock) {
if (mSocket!=null) {
return;
}
mSocket = mServerSocket.accept();
in = mSocket.getInputStream();
out = new PrintWriter(mSocket.getOutputStream());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
} public void begin_listen() {
while (mSocket==null) {
connect();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
new Thread() {
@Override
public void run() {
try {
while (!mSocket.isClosed()) {
byte[] bt = new byte[50];
in.read(bt);
String content = new String (bt, "UTF-8" );
if (content!=null && !content.equals("")) {
Message msg = new Message();
msg.obj = content;
mHandler.sendMessage(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
} public void send_msg(final String content) {
new Thread() {
@Override
public void run() {
out.print(content);
out.flush ();
}
}.start();
}
}

​ MainActivity.java

package com.zhyan8.socket_s;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends AppCompatActivity {
private Server mServer;
private EditText et_msg;
private Button btn_send;
private TextView tv_msg; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} private void init() {
et_msg = (EditText) findViewById(R.id.et_msg);
btn_send = (Button) findViewById(R.id.btn_send);
tv_msg = (TextView) findViewById(R.id.tv_msg);
btn_send.setOnClickListener(cl);
mServer = new Server(mHandler, 1111);
mServer.begin_listen();
} private View.OnClickListener cl = new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = et_msg.getText().toString().trim();
if (content!=null && !content.equals("")) {
mServer.send_msg(content);
}
}
}; private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
String content = (String) msg.obj;
tv_msg.setText(content);
}
};
}

​ activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context="com.zhyan8.socket_s.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="接收的消息:"
android:textSize="20sp"
android:gravity="center_vertical"/>
<TextView
android:id="@+id/tv_msg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center_vertical"/>
</LinearLayout> <EditText
android:id="@+id/et_msg"
android:layout_width="match_parent"
android:layout_height="100dp"
android:textSize="30sp"
android:background="#ffcc66"/> <Button
android:id="@+id/btn_send"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="发送"
android:textSize="30sp"
android:layout_marginTop="30dp"/>
</LinearLayout>

​ 界面如下:

​ 在 AndroidManifest.xml 文件的 manifest 标签下(与 application 同级)添加如下权限:

<uses-permission android:name="android.permission.INTERNET" />

4 客户端(socket_C)

​ Client.java

package com.zhyan8.socket_c;

import android.os.Handler;
import android.os.Message; import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket; public class Client{
private Socket mSocket;
private Handler mHandler;
private InputStream in;
private PrintWriter out;
private String ip;
private int port;
private Object lock = new Object(); Client(Handler handler, String ip, int port) {
mHandler = handler;
this.ip = ip;
this.port = port;
} private void connect() {
new Thread() {
@Override
public void run() {
try {
synchronized (lock) {
if (mSocket!=null) {
return;
}
mSocket = new Socket(ip, port);
in = mSocket.getInputStream();
out = new PrintWriter(mSocket.getOutputStream());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
} public void begin_listen() {
while (mSocket==null) {
connect();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
new Thread() {
@Override
public void run() {
try {
while (!mSocket.isClosed()){
byte[] bt = new byte[50];
in.read(bt);
String content = new String (bt, "UTF-8" );
if (content!=null && !content.equals("")) {
Message msg = new Message();
msg.obj = content;
mHandler.sendMessage(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
} public void send_msg(final String content) {
new Thread() {
@Override
public void run() {
out.print(content);
out.flush();
}
}.start();
}
}

​ MainActivity.java

package com.zhyan8.socket_c;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends AppCompatActivity {
private Client mClient;
private EditText et_msg;
private Button btn_send;
private TextView tv_msg; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} private void init() {
et_msg = (EditText) findViewById(R.id.et_msg);
btn_send = (Button) findViewById(R.id.btn_send);
tv_msg = (TextView) findViewById(R.id.tv_msg);
btn_send.setOnClickListener(cl);
mClient = new Client(mHandler, "192.168.0.104", 1111);
mClient.begin_listen();
} private View.OnClickListener cl = new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = et_msg.getText().toString().trim();
if (content!=null && !content.equals("")) {
mClient.send_msg(content);
}
}
}; private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
String content = (String) msg.obj;
tv_msg.setText(content);
}
};
}

​ activity_main.xml 同第3节。

​ 在 AndroidManifest.xml 文件的 manifest 标签下(与 application 同级)添加如下权限:

<uses-permission android:name="android.permission.INTERNET" />

5 效果展示

​ 客户端:

​ 服务端:

​ 声明:本文转自【Android】使用Socket实现跨设备通讯

【Android】使用Socket实现跨设备通讯的更多相关文章

  1. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

  2. Android 通过Socket 和服务器通讯

    Extends:(http://www.cnblogs.com/likwo/p/3641135.html) Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大 ...

  3. android 跨进程通讯 AIDL

    跨进程如何通讯?两个进程无法直接通讯,通过Android系统底层间接通讯.基于service的aidl实现跨进程通讯. 什么叫AIDL? Android interface definition la ...

  4. android 史上最简单易懂的跨进程通讯(Messenger)!

    不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...

  5. Android为TV端助力 史上最简单易懂的跨进程通讯(Messenger)!

    不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...

  6. Android 基于Socket的聊天应用(二)

    很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的 ...

  7. AppCompat v21 — Android 5.0之前版本设备的Material Design实现

    博客原文地址:http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html,要想打 ...

  8. [置顶] Xamarin android中使用signalr实现即时通讯

    前面几天也写了一些signalr的例子,不过都是在Web端,今天我就来实践一下如何在xamarin android中使用signalr,刚好工作中也用到了这个,也算是总结一下学到的东西吧,希望能帮助你 ...

  9. 以面向对象的思维,搭建Android与多ble蓝牙设备并发通讯小框架

    Android连接多蓝牙设备.蓝牙与多设备连接.蓝牙ble多设备并发操作.Android连接不了.Android ble开发框架.Android 连接蓝牙总结 前言 小白请绕道百度,本文适合有一定An ...

  10. IOT设备通讯,MQTT物联网协议,MQTTnet

    一.IOT设备的特性 硬件能力差(存储能力基本只有几MB,CPU频率低连使用HTTP请求都很奢侈) 系统千差万别(Brillo,mbedOS,RIOT等) 如使用电池供电,电量消耗敏感 如果是小设备, ...

随机推荐

  1. [java] JSP post 提交乱码 解决方案

    //在post提交的页面顶部插入下列代码 <% request.setCharacterEncoding("UTF-8"); %>

  2. JS - console多个值

     Promise.all([p1, p2]).then(         (res) => {           let [p1, p2] = res;           console.l ...

  3. [转帖]shell 使用sed或awk将文本中的上下两行合并为一行

    例如要装下面文本上下两行合并为一行 文件test内容: # cat test a1 ce ef 12 45 57 efef 5656 gfg 455 上下两行合并为一行: # sed -n '{N;s ...

  4. [转帖]【VIM】多行缩进空格与删除

    向前或向后缩进一个TAB 按ctrl + v组合键进入Visual Line模式,可使用方向键选择多行: 按<或>,进行向前或向后缩进tab. 缩进n个TAB,按n+<或> 多 ...

  5. [转帖]Oracle迁移到MySQL时数据类型转换问题

    https://www.cnblogs.com/yeyuzhuanjia/p/17431979.html 最近在做"去O"(去除Oracle数据库)的相关工作,需要将Oracle表 ...

  6. [转帖]50年来Intel CPU变化有多大?频率从0.75MHz提升到5.2GHz

    https://m.baidu.com/bh/m/detail/ar_9297450181050583423?data_from=lemon 今天(11月15日)是Intel推出4004处理器50周年 ...

  7. Oracle DBCA 静默删除以及建库的脚本

    No.1 背景 公司最近有一个测试环境需要重新备份恢复 但是里面有6个数据库实例 400多G的数据文件. 一般情况下 需要drop user xxx cascade ; 然后执行 drop table ...

  8. MySQL批量执行SQL修改视图属主的办法

    前人挖坑 后人填坑 Study From https://blog.csdn.net/carefree2005/article/details/109812943 第一步: 形成SQL select ...

  9. ARC150D - Removing Gacha (树上期望)

    Link 题意: 给一棵 \(n\) 个节点的树,称一个点是好的,当且仅当它到根的路径上都是黑色(包括自己).每次在不好的节点中随机选一个把它涂成黑色(不管原来它是否是白的),直到所有点都是好的为止. ...

  10. 【解决一个小问题】golang 的 `-race`选项导致 unsafe代码 panic

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 为了提升性能,使用 unsafe 代码来重构了凯撒加密的代 ...