·长连接和短连接
说到连接,首先要分清长连接和短连接。长连接,就是连接一次后,进行多次通信,通常通信比较频繁的,使用长连接比较多;短连接,就是连接后,进行通信一次,然后关闭连接,下次通信的时候,再开连接,通常通信不频繁的时候使用短连接。长连接和短连接的关系和TCP,UDP没有关系,不能混淆了。另外,长连接因为需要保持连接畅通,所以需要用心跳机制进行检测和维持。
·socket简介
再说到socket,对于不同编程语言,基本上都有自己的socket连接方式,现只对java的socket进行说明。
socket是网络通信中的一种常见的通信方式。它分为客户端socket和服务器端ServerSocket,一般而言,服务器端socket就像接线员一样,创建后一直处于等待接入电话的状态(声明端口后的ServerSocket,调用ServerSocket的阻塞方法accept()),客户端需要知道对方的号码(服务器端的IP和端口),然后拨号过去,双方连接确认后,就可以开始通信了。其中客户端是拨号端,只能拨一个号码,即客户端只有一个;但服务器端有可能还会收到其他电话的来电,所以可以收到不同号码的来电(暂理解为多进程处理的)。
socket根据底层通信方式的不同,又分为基于TCP协议的Socket和基于UDP方式的Socket。其中前者用的多一点。
·socket代码简写
基于TCP协议的socket
服务器端:
<pre name="code" class="java">
Socket socket = serverSocket.accept(); // 这是一个阻塞方法,当收到连接后,才继续往下走。这里我理解为,收到客户端的连接后,本质是拿到客户端Socket类的实例。
InputStream inputStream = socket.getInputStream(); // Socket类实例的输入流。读取客户端发来的数据。
OnputStream onputStream = socket.getOnputStream(); // Socket类实例的输出流。写入发给客户端的数据。
</pre>
客户端:
<pre name="code" class="java">
InputStream inputStream = socket.getIutputStream();// Socket类实例的输入流。读取服务器端发来的数据。
OutputStream outputStream = socket.getOutputStream();// Socket类实例的输出流。写入发给服务器端的数据。
</pre>
其中写入数据使用outputStream.write()方法,读入数据的时候分两种情况。阻塞方法和非阻塞方法。
阻塞方法是监视缓冲区的内容,有内容时就往下执行,没有内容时就一直处于等待状态(socket有一个方法可以设置等待时间。默认为0,一直等待);
非阻塞方法是不管缓冲区中的内容,一直读取缓冲区的内容,取出后判非空的情况下做处理。
阻塞方法使用的:inputStream.read()方法。代码如下:
<pre name="code" class="java">
byte buffer [] = new byte[4*1024];
while((temp = inputStream.read(buffer)) != -1){
// 读取后处理
}
</pre>
非阻塞方法:
//TODO
基于UDP协议的socket
服务器端:
<pre name="code" class="java">
DatagramSocket socket = new DatagramSocket(1234); // 创建一个DatagramSocket对象,并指定端口
byte data [] = new byte[1024];
DatagramPacket packet = new DatagramPacket(data,data.length); //创建一个空的DatagramPacket对象
socket.receive(packet);//使用receive方法接收客户端所发送的数据,接收后放在packet包中
String result = new String(packet.getData(),packet.getOffset(),packet.getLength());//使用String类型接受数据
</pre>
客户端:
<pre name="code" class="java">
DatagramSocket socket = new DatagramSocket(4567);//创建一个DatagramSocket对象
InetAddress serverAddress = InetAddress.getByName("127.0.0.0");//连接地址对象
String str = "hello";
byte data [] = str.getBytes();
DatagramPacket packet = new DatagramPacket(data,data.length,serverAddress,4567);//包和连接地址,端口关联起来
socket.send(packet);//发送包
</pre>