Android网络编程Socket

28次阅读

共计 3567 个字符,预计需要花费 9 分钟才能阅读完成。

Socket 在 Android 网络编程中,有着非常重要的作用。

Socket 基本概念

即套接字,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP 协议族 的编程接口(API)。
从设计模式的角度看来,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Socket 接口后面,对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议。
借用下网上结构图:

IP 地址和端口号组成了 Socket,都是成对出现。

Socket ={(IP 地址 1:PORT 端口号),(IP 地址 2:PORT 端口号)}

单独的 Socke 是没用任何作用的, 基于一定的协议(TCP 或者 UDP)下的 Socket 编程才能进行数据传输。

Socket 工作流程


服务端先初始化 Socket,然后与端口绑定 (bind),对端口进行监听(listen),调用 accept 阻塞,等待客户端连接。
客户端初始化一个 socket,然后连接服务器 (connect),如果连接成功,这时客户端与服务端的连接就建立了。
客户端发送数据请求,服务端接收请求并处理请求,然后把回应数据发给客户端,客户端读取数据,最后关闭数据,一次交互结束。

分类

Socket 使用类型有两种:

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

基于 TCP 的 Socket 编程

主要 API

Socket

构造方法

public Socket(String host, int port)
        throws UnknownHostException, IOException

创建流套接字并将其连接到指定主机上的指定端口号。

  • host: 主机地址
  • port: 端口号

getInputStream

返回 Socket 的输入流,用户接受数据。

getOutputStream

返回 Socket 的输出流,用于发送数据。

ServerSocket

Socket 的服务端实现

构造函数

public ServerSocket(int port) throws IOException

创建服务端 Socket,绑定到指定端口。

  • port: 端口号

accept

public Socket accept() throws IOException

监听并接受到此套接字的连接。该方法将阻塞,直到建立连接。

示例

服务端

public class Server {public static void main(String[] args) throws IOException {
        //1. 创建 ServerSocket
        ServerSocket serverSocket = new ServerSocket(8888);
        //2. 监听
        Socket socket = serverSocket.accept();
        System.out.println("server start listen");
        //3. 输入流
        InputStream is = socket.getInputStream();
        InputStreamReader reader = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(reader);
        String content = null;
        StringBuffer sb = new StringBuffer();
        while ((content = br.readLine()) != null) {sb.append(content);
        }

        System.out.println("server receiver:" + sb.toString());

        socket.shutdownInput();

        br.close();
        reader.close();
        is.close();

        socket.close();
        serverSocket.close();}
}

非常简单的 Socket 服务端,接收到客户端的数据,就会关闭当前的连接。这个示例只是展示了一个完整的流程。
如果需要复杂的服务端实现,可以使用 Netty、Mina 或者其他 Socket 框架。

客户端

//1. 创建客户端
Socket socket = new Socket("your ip", 8888);
//2. 输出流
OutputStream os = socket.getOutputStream();
//3. 发送数据
os.write("Hello world".getBytes());
System.out.println("send message");
os.flush();

socket.shutdownOutput();

os.close();
socket.close();

客户端就是连接后,发送了一份数据,就关闭连接了。
这样就实现了客户端和服务端的通信。

基于 UDP 的 Socket 编程

主要 API

DatagramPacket

用来包装接收和发送的数据。

  • 构造接收数据包
public DatagramPacket(byte[] buf,int length)

用来接收长度为 length 的数据包。

  • 构造发送数据包
DatagramPacket(byte[] buf, int length,SocketAddress address)
DatagramPacket(byte[] buf, int length, InetAddress address, int port)

用来将长度为 length 的包发送到指定主机上的指定端口号。

DatagramSocket

用来发送和接收数据报包的套接字。

构造方法

// 创建数据报套接字并将其绑定到本地主机上的指定端口
DatagramSocket(int port)  

// 创建数据报套接字,将其绑定到指定的本地地址
DatagramSocket(int port, InetAddress laddr)     

发送数据

void send(DatagramPacket p)

DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号

接收数据

void receive(DatagramPacket p) 

当此方法返回时,DatagramPacket 的缓冲区填充了接收的数据。

示例

服务端

public class UDPServer {public static void main(String[] args) throws IOException {byte[] buf = new byte[1024];
        // receive
        // 1.create
        DatagramPacket packet = new DatagramPacket(buf, buf.length);
        // 2.create udp socket
        DatagramSocket socket = new DatagramSocket(8888);
        // 3. receive start
        socket.receive(packet);
        // 4. receive data
        System.out.println("sever:" + new String(buf, 0, buf.length));

        // send
        DatagramPacket p = new DatagramPacket(buf, buf.length, 
                        packet.getAddress(), packet.getPort());
        socket.send(p);
        socket.close();}
}

客户端

// send
InetAddress address = InetAddress.getByName("your ip");
//1.create packet
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 8888);
//2.create socket
DatagramSocket socket = new DatagramSocket();
//3.send data
socket.send(packet);
// receive
//1.create packet
final byte[] bytes = new byte[1024];
DatagramPacket receiverPacket = new DatagramPacket(bytes, bytes.length);
socket.receive(receiverPacket);
System.out.println("client:" + new String(bytes, 0, bytes.length));

socket.close();

客户端和服务端的实现,都比较简单。

关于 Socket 编程,就介绍好了,这篇只是开了头,最主要的还是得去项目中实践。

参考

  • Android:这是一份很详细的 Socket 使用攻略
  • Scoket 编程

本篇文章由一文多发平台 ArtiPub 自动发布

正文完
 0