基于 Socket 的 Android与树莓派通信

个人博客地址:http://icharles.top/2018/04/29/Socket/

一、Socket定义

  • 即套接字,是一个对 TCP / IP协议进行封装 的编程调用接口(API)

    1.即通过Socket,我们才能在Andorid平台上通过 TCP/IP协议进行开发
    2.Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)
    
  • 成对出现,一对套接字:
    Socket ={(IP地址1:PORT端口号),(IP地址2:PORT端口号)}

二、Socket基本通信模型

Socket的使用类型主要有两种:

流套接字(streamsocket) :基于 TCP协议,采用 流的方式 提供可靠的字节流服务
数据报套接字(datagramsocket):基于 UDP协议,采用 数据报文 提供数据打包发送的服务

具体原理图如下:
socket

三、使用基于TCP协议的Socket

    Socket通信主要分为服务端和客服端   

一个客户端要发起一次通信,首先必须知道运行服务器端的主机IP地址。然后由网络基础设施利用目标地址,将客服端发送的信息传递到正确的主机上,在Java中,地址可以由一个字符串来定义,这个字符串可以使用数字型的地址(比如192.168.1.1),也可以是主机名(example.com)。在Java当中InetAddress类代表了一个网络目标地址,包括主机名和数字类型的地址信息。
基于TCP协议操作Socket的API

服务端

1)、创建ServerSocket的方法

ServerSocket(int localPort);
ServerSocket(int localPort, int queueLimit);
ServerSocket(int localPort, int queueLimit, InetAddress localAddr);

创建一个ServerSocket必须指定一个端口,以便客户端能够向端口号发送连接请求。端口的有效范围是0~65535
2)、ServerSocket操作
Socket accept()——此方法为下一个传入的连接请求创建Socket实例,并将已经成功连接的Socket实例返回给服务器套接字,如果没有连接请求,accept()方法将阻塞等待
void close()——此方法用于关闭套接字

客户端

1)、创建Socket的方法
Socket(InetAddress remoteAddress, int remotePort);
利用Socket的构造函数,可以创建一个TCP套接字后,先连接到指定的远程地址和端口号
2)、操作Socket的方法
InputStream getInputStream();
OutputStream getOutputStream();
void close();

四、使用UDP的Socket

1)、创建DatagramPacket
DatagramSocket(byte[] data, int offset, int length, InetAddress remoteAddr, int remotePort);
该构造函数创建一个数据报文对象,数据包含在第一个参数中
2)、创建DatagramSocket
DatagramSocket(int localPort);
该构造函数将创建一个UDP套接字
3)、DatagramSocket:发送和接收
void send(DatagramPacket packet);——此方法用来发送DatagramPacket实例,一旦创建连接,数据报将发送到该套接字所连接的地址
void receive(DatagramPacket packet);——此方法将阻塞等待,直到接收到数据报文,并将报文中的数据复制到指定的DatagramPacket实例中

五、操作总结

服务器端编程步骤:
1、创建服务器端套接字并绑定到一个端口上
2、套接字设置监听模式等待连接请求
3、接收连接请求后进行通信
4、返回,等待另一个连接请求

客户端编程步骤:
1、创建客户端套接字(指定服务器端的IP地址和端口号)
2、连接(Android创建Socket时会自动连接)
3、与服务器端进行通信
4、关闭套接字

Android Socket通信原理,注意地方:
1、中间的管道连接是通过InputStream/OutputStream流实现的
2、一旦管理建立起来可以进行通信
3、关闭管道的同时意味着关闭Socket
4、当对同一个Socket创建重复管道时会异常
5、通信过程中顺序很重要:服务器端首先得到输入流,然后将输入流信息输出到其各个 客户端;客户端先建立连接后先写入输出流,然后再获得输入流,不然会有EOFException的异常。

六、具体实例

步骤1:添加网络权限

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

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.robot.charles.hexapod">

    <!--允许应用程序改变网络状态-->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

    <!--允许应用程序改变WIFI连接状态-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

    <!--允许应用程序访问有关的网络信息-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <!--允许应用程序访问WIFI网卡的网络信息-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    <!--允许应用程序完全使用网络-->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

步骤2:布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@color/colorBackground"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/tv_hexapod"
            style="@style/Text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:gravity="center_horizontal"
            android:text="Hexapod Controler" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <EditText
                android:id="@+id/et_input"
                android:layout_width="180dp"
                android:layout_height="40dp"
                android:layout_marginLeft=
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值