Android 网络编程——Socket

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个针对TCP和UDP编程的接口(API),通过Socket,我们才能使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口。

一.利用Socket建立网络连接的步骤

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

1。服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

2。客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

3。连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

二.Socket 一般有两种类型:TCP 套接字和 UDP 套接字

1.使用 TCP 通信
TCP 服务器端工作的主要步骤如下:
步骤 1 调用 ServerSocket(int port)创建一个 ServerSocket,并绑定到指定端口上。
步骤 2 调用 accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字。
步骤 3 调 用 Socket 类 的 getOutputStream() 和 getInputStream() 获 取 输 出 和 输 入 流,开始网络数据的发送和接收。
步骤 4 关闭通信套接字。

// 创建一个 ServerSocket 对象
ServerSocket serverSocket = null;
try {
	// TCP_SERVER_PORT 为指定的绑定端口,为 int 类型
	serverSocket = new ServerSocket(TCP_SERVER_PORT);
	// 监听连接请求
	Socket socket = serverSocket.accept();
	// 写入读 Buffer 中
	BufferedReader in = new BufferedReader(new
	// 获取输入流
	InputStreamReader(socket.getInputStream()));
	// 放到写 Buffer 中
	BufferedWriter out = new BufferedWriter(new
	// 获取输出流
	OutputStreamWriter(socket.getOutputStream()));
	// 读取接收信息,转换为字符串
	String incomingMsg = in.readLine() + System.getProperty("line.separator");
	// 生成发送字符串
	String outgoingMsg = "goodbye from port " + TCP_SERVER_PORT +
	System.getProperty("line.separator");
	// 将发送字符串写入上面定义的 BufferedWriter 中
	out.write(outgoingMsg);
	// 刷新,发送
	out.flush();
	// 关闭
	socket.close();
} catch (InterruptedIOException e) {
	// 超时错误
	e.printStackTrace();
	// IO 异常
} catch (IOException e) {
	// 打印错误
	e.printStackTrace();
} finally {
	// 判定是否初始化 ServerSocket 对象,如果初始化则关闭 serverSocket
	if (serverSocket != null) {
		try {
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


TCP 客户端工作的主要步骤如下:
步骤 1 调用 Socket() 创建一个流套接字,并连接到服务器端。
步骤 2 调 用 Socket 类 的 getOutputStream() 和 getInputStream() 方 法 获 取 输 出 和 输 入流,开始网络数据的发送和接收。
步骤 3 关闭通信套接字。

try {
	// 初始化 Socket,TCP_SERVER_PORT 为指定的端口,int 类型
	Socket socket = new Socket("localhost", TCP_SERVER_PORT);
	// 获取输入流
	BufferedReader in = new BufferedReader(new
	InputStreamReader(socket.getInputStream()));
	// 生成输出流
	BufferedWriter out = new BufferedWriter(new
	OutputStreamWriter(socket.getOutputStream()));
	// 生成输出内容
	String outMsg = "TCP connecting to " + TCP_SERVER_PORT +
	System.getProperty("line.separator");
	// 写入
	out.write(outMsg);
	// 刷新,发送
	out.flush();
	// 获取输入流
	String inMsg = in.readLine() + System.getProperty("line.separator");
	Log.i("TcpClient", "received: " + inMsg);
	// 关闭连接
	socket.close();
} catch (UnknownHostException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

2.使用 UDP 通信
UDP 服务器端工作的主要步骤如下:
步骤 1 调用 DatagramSocket(int port) 创建一个数据报套接字,并绑定到指定端口上。
步骤 2 调用 DatagramPacket(byte[]buf,int length),建立一个字节数组以接收 UDP 包。
步骤 3 调用 DatagramSocket 类的 receive(),接受 UDP 包。
步骤 4 关闭数据报套接字。

// 接收的字节大小,客户端发送的数据不能超过 MAX_UDP_DATAGRAM_LEN
byte[] lMsg = new byte[MAX_UDP_DATAGRAM_LEN];
// 实例化一个 DatagramPacket 类
DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
// 新建一个 DatagramSocket 类
DatagramSocket ds = null;
try {
	// UDP 服务器监听的端口
	ds = new DatagramSocket(UDP_SERVER_PORT);
	// 准备接收数据
	ds.receive(dp);
} catch (SocketException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
} finally {
	// 如果 ds 对象不为空,则关闭 ds 对象
	if (ds != null) {
		ds.close();
	}
}



UDP 客户端工作的主要步骤如下:
步骤 1 调用 DatagramSocket() 创建一个数据包套接字。
步骤 2 调用 DatagramPacket(byte[]buf,int offset,int length,InetAddress address,int port),建立要发送的 UDP 包。
步骤 3 调用 DatagramSocket 类的 send() 发送 UDP 包。
步骤 4 关闭数据报套接字。

// 定义需要发送的信息
String udpMsg = "hello world from UDP client " + UDP_SERVER_PORT;
// 新建一个 DatagramSocket 对象
DatagramSocket ds = null;
try {
	// 初始化 DatagramSocket 对象
	ds = new DatagramSocket();
	// 初始化 InetAddress 对象
	InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
	DatagramPacket dp;
	// 初始化 DatagramPacket 对象
	dp = new Datagram
	Packet(udpMsg.getBytes(), udpMsg.length(), serverAddr, UDP_SERVER_PORT);
	// 发送
	ds.send(dp);
	// 异常处理
	// Socket 连接异常
}catch (SocketException e) {
	e.printStackTrace();
	// 不能连接到主机
}catch (UnknownHostException e) {
	e.printStackTrace();
	// 数据流异常
} catch (IOException e) {
	e.printStackTrace();
	// 其他异常
} catch (Exception e) {
	e.printStackTrace();
} finally {
	// 如果 DatagramSocket 已经实例化,则需要将其关闭
	if (ds != null) {
	ds.close();
	}
}


 

猜你喜欢

转载自blog.csdn.net/WYYZ5/article/details/48130919