一.Socket简介
socket是插座的意思,通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。应用程序通过socket向网络发送(应答)请求。java中有两种socket:
服务端的ServerSocket:不主动发送请求,只是来监听端口,主要用来应答请求。
客户端的Socket:用来发送请求。
二.Socket通信
socket有两种通信方式:基于TCP协议的通信和基于UDP协议的通信。发送方和接收方使用的协议要一致。
基于TCP协议:传输过程是基于“流”的,特点是通信时建立连接,确保接收方接到数据,因此是相对安全的。缺点是慢一些。
基于UDP协议:传输过程是基于“包”的,特点是并不建立连接,发送方只管发送数据,并不关心接收方是否收到。优点是很快。
三. 基于TCP协议的Socket
1.连接过程
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
2.重要API
accept()方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
3.代码示例:
服务端:
ServerSocket serversocket=new ServerSocket(4567); //创建服务端socket,并使之监听4567端口。
Socket socket=serversocket.accept(); //用于接收客户端发来的请求socket,是一个阻塞方法,当没有请求时,会发生阻塞。
socket.getInputStream(); //得到输入流,接下来对输入流进行处理即可。
......
serversocket.close(); //显式关闭serversocket,避免浪费资源。
客户端:
Socket socket=new Socket("192.168.1.104",4567); //创建客户端socket,两个参数分别是发送目标的IP和端口号,
//其实就是指定作为发送目标的服务端套接字。
OutputStream outputstream=socket.getOutputStream(); //创建输出流,接下来对输出流进行写操作,
......
socket.close(); //显式关闭socket,避免浪费资源。
四.基于UDP协议的Socket
1.特点
UDP发送过程不是基于流的,而是以包为单位。
2.代码示例
服务端:
DatagramSocket socket = new DatagramSocket (4567); //创建服务端socket,并使之监听4567端口。
//注意,DatagramSocket使用的就是UDP协议。
byte data[]=new byte[1024];
DatagramPacket packet = new DatagramPacket (data,data.length); //数据包中放的空data来准备接受数据。
socket.receive(packet); //类似于TCP中的accept方法,用来接收客户端发来的数据,也是阻塞方法。
String s=packet.getData(); //接收数据。
特别的,当数据小于1024是,由于data指定的是1024,所以会出现乱码,解决的办法是:
String s=new String(packet.getData(),packet.getOffset(),packet.getLength());
客户端:
DatagramSocket socket = new DatagramSocket (4567); //创建客户端socket。
InetAddress serverAddress=InetAddress.getByName("192.168.1.104"); //服务端地址。
DatagramPacket packet = new DatagramPacket (data,data.length,serverAddress,4567); //data是要发送的数据,packet携带数据,
//IP,端口号信息,就像是写好了内容的信,信封上有接收方地址。
socket.send(packet ); //发送。