【Android】Socket通讯示例(服务端/客户端)

来源:互联网 发布:nginx日志分析软件 编辑:程序博客网 时间:2024/04/27 11:03

1.概述

一个简单的Socket通信示例,用于实现Java服务端与Android客户端间的通讯。

整体逻辑
Server端:新开一个线程,启动Server服务端,使用while监听当前端口是否已经进入阻塞状态,如果进入,则表示有连接请求,进行处理(接收/发送消息,这里我设置的是一次通讯–通讯完毕后关闭服务端);
Client端:打开App,输入要发送的内容,点击发送按钮开始新建线程建立Socket请求进行数据的发送、读取。

数据读写方式
java.io.DataOuputStream.writeUTF(String str)// 方法将一个字符串写入使用经修订的UTF-8编码的基础输出流
可能产生异常:
IOException – 如果发生I/O错误。

java.io.DataInputStream.readUTF()// 方法读取在已使用UTF-8修改版格式编码的字符串。字符的字符串从UTF解码,并返回为字符串
可能产生异常:
IOException – 如果流已关闭或发生或任何I/ O错误。
EOFException – 如果输入流已经到达末端。
UTFDataFormatException – 如果字节不表示一个有效的经修订的UTF-8编码。

2.服务端代码

package com.zihao.socketserver;import java.io.DataInputStream;import java.io.DataOutputStream;import java.net.ServerSocket;import java.net.Socket;/** * @ClassName:SocketServer * @Description:TODO<Socket服务端代码> * @author:zihao * @date:2015年12月21日 下午3:42:12 * @version:v1.0 */public class SocketServer implements Runnable {    private static final String TAG = "【服务器】";    private static final int PORT = 54321;// 端口号    public void run() {        try {            // // 创建ServerSocket            ServerSocket serverSocket = new ServerSocket(PORT);            System.out.println(TAG + "已启动.");            // 一旦有堵塞,则表示服务器与客户端获得了连接            while (true) {                // 判断服务端是否已是关闭状态                if (serverSocket.isClosed()) {// 服务端已关闭                    return;                }                // 接受客户端请求                Socket client = serverSocket.accept();                System.out.println(TAG + "接受客户端连接请求.");                // 用于接收客户端消息                DataInputStream dis = new DataInputStream(                        client.getInputStream());                // 用于向客户端发送消息                DataOutputStream dos = new DataOutputStream(                        client.getOutputStream());                try {                    String str = dis.readUTF();                    System.out.println(TAG + "收到内容:" + str);                    String outStr = "服务器反馈的消息";                    System.out.println(TAG + "发送内容:" + outStr);                    dos.writeUTF(outStr);                    dos.flush();                    // 关闭流                    dis.close();                    dos.close();                } catch (Exception e) {                    e.printStackTrace();                } finally {                    // 关闭                    client.close();                    System.out.println(TAG + "关闭与客户端连接");                    serverSocket.close();                    System.out.println(TAG + "关闭");                }            }        } catch (Exception e) {            e.printStackTrace();        }    }    // main函数,开启服务器    public static void main(String a[]) {        Thread desktopServerThread = new Thread(new SocketServer());        desktopServerThread.start();    }}

3.Android客户端代码

package com.example.socketclient;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.net.Socket;import java.net.SocketAddress;import java.net.SocketTimeoutException;import android.util.Log;/** * @ClassName:SocketRequest * @Description:TODO<Socket请求线程类> * @author:zihao * @date:2015年12月18日 上午9:22:56 * @version:v1.0 */public class SocketRequest extends Thread {    private static final String TAG = SocketRequest.class.getSimpleName();    private String mServerHost;// 服务器地址    private int mServerPort;// 服务端口号    private String mSendMessage;// 要发送的消息    public SocketRequest(String serverHost, int serverPort, String sendMessage) {        // TODO Auto-generated constructor stub        this.mServerHost = serverHost;        this.mServerPort = serverPort;        this.mSendMessage = sendMessage;    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        Socket socket = new Socket();        try {            Log.d(TAG, "请求连接到服务器...");            SocketAddress socketAddress = new InetSocketAddress(mServerHost,                    mServerPort);            socket.connect(socketAddress, 5 * 1000);// 设置目标地址,请求超时限制            // 判断是否连接成功            if (socket.isConnected()) {                // 发送消息                DataOutputStream dos = new DataOutputStream(                        socket.getOutputStream());                Log.d(TAG, "连接成功,开始发送消息,发送内容:" + mSendMessage);                dos.writeUTF(mSendMessage);// 服务区/客户端双方的写/读方式要一直,否则会报错                dos.flush();// 刷新输出流,使Server马上收到该字符串                // 接收服务器消息                DataInputStream dis = new DataInputStream(                        socket.getInputStream());                Log.d(TAG, "接收到服务器反馈消息:" + dis.readUTF());                dos.close();                dis.close();            } else {                Log.e(TAG, "未能成功连接至服务器!");            }        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();            if (e instanceof SocketTimeoutException) {                Log.e(TAG, "连接超时!");            } else {                Log.e(TAG, "通讯过程发生异常:" + e.toString());            }        } finally {            try {                socket.close();                this.interrupt();                Log.d(TAG, "关闭连接.");            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

调用方法

new SocketRequest("服务器地址", 端口号, "要发送的内容").start();

使用权限

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