发表于: 2017-07-01 23:49:57
1 1056
一今天完成的事情:
今天准备评审的,结果今天方案太多,没有轮的上,大佬们没时间.
今天想说一下socket编程
我们在http中使用soket编程很多
长连接,短链接:
短链接: 短链接的工作方式是这样的:建立连接--发送数据--关闭连接。规范一点的说法就是:每次进行数据传输时,需要首先建立TCP连接,传输完数据之后就关闭连接。下次有数据传输的时候再家里连接。比如说咱们常用的HTTP连接(当然HTTP连接也可以作为一种长连接)。 长连接: 长连接的工作方式是这样的:建立连接--发送数据--保持连接--发送数据........--关闭连接 规范一点就是:在一个TCP连接之内可以多次的进行数据传输。 两者的应用场景: 长连接因为需要长时间的保持连接,所以对网络资源或这端口的占用十分的严重,所以长连接常用于频繁操作的任务,并且连接数不是非常大。 短链接则相反,对于那些不是频繁操作的任务,可以选择短链接,而且短链接可以支持非常大的任务数,毕竟它对资源的占用有限。
SOCKET连接的一个基本套路:服务器监听--客户端端请求--连接确认。
一般来说,我们在进行SOCKET编程的时候,基本步骤:
1、首先就是在服务端创建一个ServerSocket,对某个端口进行监听。
2、在客户端创建SOKET,对某个地址进行请求
3.服务端和客户端建立连接之后,通过IO流进行数据的传输。
4、第四步:关闭连接,释放资源
基本的步骤就是上面那样的,咱们来撸点代码来具体看一下。
服务器端:
public class SocketListenTest implements InitializingBean { /** *在这里,实现InitializingBean,在工程应用启动之后,就会启动afterPropertiesSet(),从而实现对端口的监听 */ private static final Logger logger = LoggerFactory.getLogger(SocketListenTest.class); //定义线程池,实现服务器的多线程的处理请求 private static ExecutorService threadPool = Executors.newFixedThreadPool(5); @Override public void afterPropertiesSet() throws Exception { logger.info("ServerSocket监听开始,开始时间:"+ DateUtil.getStringFromDate(new Date(),DateUtil.FORMAT_DATETIME)); new Thread(new ServerSocketListen()).start(); logger.info("ServerSocket监听结束,开始时间:"+ DateUtil.getStringFromDate(new Date(),DateUtil.FORMAT_DATETIME)); } class ServerSocketListenimplements Runnable{ @Override public void run() { try{ /** * 第一步:创建ServerSocket,监听9999,也就是咱们说的服务端进行监听 */ ServerSocket serverSocket = new ServerSocket(9999); logger.info("创建服务器端Socket,绑定并监听端口,端口号:"+9999); Socket acceptSocket = null; while(true){ /** * 第二步:通过ServerSocket创建服务器Socket,用于与客户端进行数据传输 */ acceptSocket = serverSocket.accept(); threadPool.submit(new SocketDealThread(acceptSocket)); } }catch(Exception e){ String msg = "监听线程异常结束,时间:"+DateUtil.getStringFromDate(new Date(),DateUtil.FORMAT_DATETIME); logger.error(msg,e); } } } class SocketDealThread implements Runnable{ private Socket socket; private SocketDealThread(Socket socket){ this.socket = socket; } @Override public void run() { DataInputStream dataInputStream = null; DataOutputStream dataOutputStream = null; try{ logger.info("处理Socket请求,获取输入流,并读取客户端信息"); /** * 第三步:获取输入流,调用socket.getInputStream()获取输入流,获取客户端输入的数据 * 注意:这里用了readUTF(),采用了UTF-8编码对流数据进行转换,最好客户端写入数据的时候使用writeUTF() */ dataInputStream = new DataInputStream(socket.getInputStream()); String contentStr = dataInputStream.readUTF(); logger.info("处理Socket请求,请求报文:"+contentStr); /** * 第四步:调用socket.getOutputStream()获取输出流,向客户端进行数据的输出 */ dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataOutputStream.writeUTF("YES"); }catch(Exception ex){ String strErrorMsg = "处理Socket请求异常"; logger.error(strErrorMsg, ex); }finally{ /** * 第五步:关闭socket的资源 */ logger.info("处理Socket请求,资源关闭开始"); try { if(dataOutputStream != null){ dataOutputStream.close(); } } catch (IOException e) { logger.error("关闭写管道异常",e); } try { if(dataInputStream != null){ dataInputStream.close(); } } catch (IOException e) { logger.error("关闭读管道异常",e); } try { socket.close(); } catch (IOException e) { logger.error("关闭socket异常",e); } logger.info("处理Socket请求,资源关闭完成"); } } } }
客户端代码:
public void clientSocketTest(){ Socket socket = null; DataOutputStream dataOutputStream = null; DataInputStream dataInputStream = null; try{ /** * 第一步:创建客户端Socket,此时需要指定请求服务器的IP地址和端口号 * */ socket = new Socket("localhost",9999); /** * 第二步:获取输出流,向服务端写出数据,调用socket.getOutputStream() */ dataOutputStream = new DataOutputStream(socket.getOutputStream()); String str = "这是一条来自客户端socket的请求数据"; dataOutputStream.writeUTF(str); /** * 第三步:获取输入流,读取服务器返回的数据 */ dataInputStream = new DataInputStream(socket.getInputStream()); String returnStr= dataInputStream.readUTF(); logger.info("服务器返回的报文:"+returnStr); }catch(Exception e){ String msg = "客户端Socket出现异常,时间:"+ DateUtil.getStringFromDate(new Date(), DateUtil.FORMAT_DATETIME); logger.error(msg,e); }finally{ /** * 第四步:关于socket连接及其相关资源 */ logger.info("处理Socket请求,资源关闭开始"); try { if(dataOutputStream != null){ dataOutputStream.close(); } } catch (IOException e) { logger.error("关闭写管道异常",e); } try { if(dataInputStream != null){ dataInputStream.close(); } } catch (IOException e) { logger.error("关闭读管道异常",e); } try { socket.close(); } catch (IOException e) { logger.error("关闭socket异常",e); } logger.info("处理Socket请求,资源关闭完成"); } }
以上就是SOCKET连接的基本步骤,当然上面实现的是SOCKET短连接的实现方式。当然也可以使用SOCKT的长连接。
SOCKET实现长连接,有一个心跳机制。大体的思路是这样的: 客户端: 客户端每隔一定的时间往服务器端发送一段报文,假设我们每隔1一分钟往服务器端发送一段报文。 服务器端:服务器端要有一个相应的检测机制,没隔一段时间(我们假设两分钟)去检测有没有收到客户端发来的该段报文。如果没有,则断开连接。
二、遇到的问题无
三、明天计划的事情:
四、收获:最近对源码很感兴趣,:等复盘任务做完了多去看看
评论