Socket网络通信

Socket通信

参考:
  1. 国内博客
  2. 维基百科
  3. IBM Knowledge
  4. 国外技术分享的文章
  5. Oracle官方文档

简介

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);
   }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容