Socket通信
参考:
简介
Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信。两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。
功能上最大的差异:Http通信是客户端主动发送,服务端被动接收;Socket通信是双方互发。
分类
Socket类型为:
- 流套接字、面向连接的套接字(streamsocket,connection_oriented sockets):使用TCP、SCTP或者DCCP传输协议。
- 数据报套接字、无连接的套接字(datagramsocket,connectionless sockets):使用UDP协议。
- 原始套接字(raw socket):通常用于路由器和其他网络设备,传输绕过了传输层,应用可以获取数据头信息。
实现原理
- 流套接字
服务器端首先声明一个ServerSocket对象并且指定端口号,然后调用Serversocket的accept()方法接收客户端的数据。accept()方法在没有数据进行接收的处于堵塞状态。(Socketsocket=serversocket.accept()),一旦接收到数据,通过inputstream读取接收的数据。
客户端创建一个Socket对象,指定服务器端的ip地址和端口号(Socketsocket=newSocket("172.168.10.108",8080);),通过inputstream读取数据,获取服务器发出的数据(OutputStreamoutputstream=socket.getOutputStream()),最后将要发送的数据写入到outputstream即可进行TCP协议的socket数据传输。
- 数据包套接字
服务器端首先创建一个DatagramSocket对象,并且指点监听的端口。接下来创建一个空的DatagramSocket对象用于接收数据(bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data,data.length)),使用DatagramSocket的receive方法接收客户端发送的数据,receive()与serversocket的accepet()类似,在没有数据进行接收的处于堵塞状态。
客户端也创建个DatagramSocket对象,并且指点监听的端口。接下来创建一个InetAddress对象,这个对象类似与一个网络的发送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定义要发送的一个字符串,创建一个DatagramPacket对象,并制定要讲这个数据报包发送到网络的那个地址以及端口号,最后使用DatagramSocket的对象的send()发送数据。*(Stringstr="hello";bytedata[]=str.getByte();DatagramPacketpacket=new DatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)
TCP与UPD实现的最大的区别:TCP使用的是流的方式发送,UPD是以包的形势发送。
通信模型
网络传输中,Socket的APIs 处于应用层和传输层之间。Socket APIs本身不组成通信模型。它允许应用与传输层或者其他传统的通信模型进行交互。具体如下所示:
Java编码
伪代码:
Socket socket = getSocket(type = "TCP")
connect(socket, address = "1.2.3.4", port = "80")
send(socket, "Hello, world!")
close(socket)
Java服务端代码:
创建Socket并监听:
public void listenSocket(){
try{
server = new ServerSocket(4321);
} catch (IOException e) {
System.out.println("Could not listen on port 4321");
System.exit(-1);
}
listenSocketSocketserver.acceptSocket
try{
client = server.accept();
} catch (IOException e) {
System.out.println("Accept failed: 4321");
System.exit(-1);
}
listenSocketBufferedReaderclientPrintWriter
try{
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
}
listenSocket
while(true){
try{
line = in.readLine();
//Send data back to client
out.println(line);
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
}
客户端发代码:
public void listenSocket(){
//Create socket connection
try{
socket = new Socket("kq6py", 4321);
out = new PrintWriter(socket.getOutputStream(),
true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Unknown host: kq6py");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
}