IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Android之Socket实例 -> 正文阅读

[网络协议]Android之Socket实例

? ? Socket(套接字)是对 TCP/IP 协议的封装和应用,根据底层封装协议的不同,Socket 的类型可以分为流套接字(streamsocket)和数据报套接字(datagramsocket)两种。流套接字将TCP作为端对端协议,提供了一个可信赖的字节流服务;数据报套接字使用 UDP 协议,提供数据打包发送服务,应用程序可以通过它发送最长 64KB 的信息。Socket 的通信模型图如1-1所示。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?图1-1 Socket 的通信模型图?

? ? 通过图1-1可以很容易地看出,使用Socket进行两个应用程序之间的通信时可以选择使用TCP还是UDP作为其底层协议。对比两种方式,就会发现它们各有优劣,TCP 首先连接接收方,然后发送数据,保证成功率,速度相对较慢(相比 HTTP 方式还是非常快的);UDP 把数据打包成数据包,然后直接发送对应的IP 地址,速度快,但是不保证成功率,并且数据大小有限。

? ? 一个功能齐全的 Socket,都要包含以下基本结构,其工作过程包含4个基本的步骤∶创建Socket,打开连接到 Socket 的输入/出流,按照一定的协议对 Socket进行读/写操作,关闭 Socket。

? ? Java在java.net包中提供了 Socket 和 ServerSocket 两个类,分别用来表示双向连接的客户端和服务端,是Socket编程的核心类。构造方法很多,一般情况下使用下面两种∶

Socket client = new Socket("127.0.0.1 ",999);

ServerSocket server = new ServerSocket(999);

? ? 其中,Socket 类用于实例化一个 Client,参数分别是要访问的IP 地址和端口号,这个端口号要与服务端一致。ServerSocket类用于实例化一个 Server,其中的参数用来设置端口这里的端口不能与"3306""80""8080"等常用端口号冲突。

? ? 下面以基于TCP的Socket为例来讲解如何使用Socket。

? ? 使用Java Socket创建一个服务端程序,运行在eclipse平台,并运行在PC上,然后在手机上编写客户端程序,在局域网内访问服务端。下面先编写服务端,代码如下:

package socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class sockettest {
	public static void main(String[] args) throws IOException {
      
		@SuppressWarnings("resource")
		ServerSocket service = new ServerSocket(2226);
		
        while (true) {
            //等待客户端连接
            Socket socket = service.accept();
            new Thread(new AndroidRunable(socket)).start();
           
        }
    }

}
class AndroidRunable implements Runnable{
    Socket socket=null;
    public AndroidRunable(Socket socket)
    {
        this.socket=socket;
    }
    public void run(){
        //向Android客户端输出hello this is www.bigbirdic.com!
        String line=null;
        InputStream inputStream;
        OutputStream outputStream;
        String str="hello this is www.bigbirdic.com!";
        try{
        	
            //向客户端发送信息
            outputStream=socket.getOutputStream();
            inputStream=socket.getInputStream();
            BufferedReader bfr=new BufferedReader(new InputStreamReader(inputStream));
            outputStream.write(str.getBytes("gbk"));
            outputStream.flush();
            //半关闭Socket
            socket.shutdownOutput();
            //获取客户端的信息
            while ((line=bfr.readLine())!=null){
                    System.out.print(line);
            }
            //关闭输入输出流
            outputStream.close();
            bfr.close();
            inputStream.close();
            socket.close();
        }catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

? ? 这里的代码很简单,单纯地使用ServerSocket建立服务,设置端口号为2226,然后每当有客户端访问时就返回一个“hello this is www.bigbirdic.com!”。编辑完成服务端之后,我们在Android?Studio中创建一个用于创建Socket客户端的类,代码如下:

package com.rfstar.sockettest;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;

public class SocketUtil {
    private  String str;
    private Socket socket;
    private String ip;

    public SocketUtil(String str,String ip){
        this.str=str;
        this.ip=ip;
    }

    public String sendMessage(){
        String result="";
        try{
            socket=new Socket();
//ip为电脑所在的局域网网址
socket.connect(new InetSocketAddress(ip,2226),5000);
          OutputStream outputStream=socket.getOutputStream();
            outputStream.write(str.getBytes());
            outputStream.flush();

            BufferedReader bfr=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line=null;
            StringBuffer buffer=new StringBuffer();
            while ((line=bfr.readLine())!=null)
            {
                buffer.append(line);
            }
            result=buffer.toString();
            bfr.close();
            outputStream.close();
            socket.close();
        }catch (SocketException e)
        {
            //连接超时,在UI界面显示消息
            Log.i("socket",e.toString());
        }catch (IOException e)
        {
            e.printStackTrace();
        }
        return result;
    }
}

? ? 在本类中,使用Socket连接服务器端,然后发送相关信息并接收服务端数据。代码并不难,下面就在MainActivity中使用此类。当然,使用它之前要先修改MainActivity的布局文件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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="50dp"
        android:textSize="24sp"/>
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="发送消息"
        android:textSize="20dp"/>
    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        />
</LinearLayout>

? ? 这里使用一个EditText来编辑向服务端发送的内容,并用一个Button来点击触发网络通信的事件,然后用一个TextView展示服务端返回的值。接下来在MainActivity中通过findViewById()方法来获取这些控件,并设置Button的点击事件,代码如下:

package com.rfstar.sockettest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import org.w3c.dom.EntityReference;

public class MainActivity extends AppCompatActivity {
    private Button button;
    private TextView textView;
    private String result;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            if(msg.what==123)
            {
                textView.setText(result);
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView()
    {
        textView=(TextView)findViewById(R.id.content);
        final EditText editText=(EditText)findViewById(R.id.message);
        button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        result=new SocketUtil(editText.getText().toString(),"192.168.110.82").sendMessage();
                        handler.sendEmptyMessage(123);
                    }
                }).start();
            }
        });
    }
}

至此,实例代码完成,不要忘了还要在AndroidManifest.xml中申请权限:

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

? ? 在Activity中只是对点击事件做了处理,并将服务端返回的值展示在TextView上。添加完网络权限之后,运行程序,在EditText中输入内容,然后点击“发送消息”按钮,将“hello”发送到服务端,并接收到服务端返回的“hello this is www.bigbirdic.com!”,如图1-2所示。

观察服务端代码所在的控制台,发现也确实接收到了手机发送的内容,如图1-3所示。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?图1-2?Socket的通信:客户端发送并接收响应的消息

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?图1-3?Socket通信:服务端接收到消息?

源码下载地址:链接:https://pan.baidu.com/s/1ExoSxaQRdjmwUUnDuSbUIQ 提取码:43ka

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-08 14:25:09  更:2022-01-08 14:27:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:45:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码