亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用 Java 類 實現(xiàn)Http協(xié)議

 更新時間:2021年09月06日 16:45:25   作者:冰 河  
這篇文章主要介紹了用幾個Java類簡單的實現(xiàn)了Http協(xié)議相關(guān)資料,感興趣的的朋友可以參考下面具體的文章內(nèi)容

Java 實現(xiàn)Http協(xié)議

HTTP協(xié)議屬于應(yīng)用層協(xié)議,它構(gòu)建于TCP和IP協(xié)議之上,處于TCP/IP協(xié)議架構(gòu)層的頂端,所以,它不用處理下層協(xié)議間諸如丟包補(bǔ)發(fā)、握手及數(shù)據(jù)的分段及重新組裝等繁瑣的細(xì)節(jié),使開發(fā)人員可以專注于應(yīng)用業(yè)務(wù)。

協(xié)議是通信的規(guī)范,為了更好的理解HTTP協(xié)議,我們可以基于Java的Socket API接口,通過設(shè)計一個簡單的應(yīng)用層通信協(xié)議,來簡單分析下協(xié)議實現(xiàn)的過程和細(xì)節(jié)。

在我們今天的示例程序中,客戶端會向服務(wù)端發(fā)送一條命令,服務(wù)端在接收到命令后,會判斷命令是否是“HELLO”,如果是“HELLO”, 則服務(wù)端返回給客戶端的響應(yīng)為“hello”,否則,服務(wù)端返回給客戶端的響應(yīng)為“bye bye”。

我們接下來用Java實現(xiàn)這個簡單的應(yīng)用層通信協(xié)議,

一、協(xié)議請求的定義

協(xié)議的請求主要包括:編碼、命令和命令長度三個字段。

package com.binghe.params;
/**
 * 協(xié)議請求的定義
 * @author binghe
 *
 */
public class Request {
 /**
  * 協(xié)議編碼
  */
 private byte encode;
 
 /**
  * 命令
  */
 private String command;
 
 /**
  * 命令長度
  */
 private int commandLength;

 public Request() {
  super();
 }

 public Request(byte encode, String command, int commandLength) {
  super();
  this.encode = encode;
  this.command = command;
  this.commandLength = commandLength;
 }

 public byte getEncode() {
  return encode;
 }

 public void setEncode(byte encode) {
  this.encode = encode;
 }

 public String getCommand() {
  return command;
 }

 public void setCommand(String command) {
  this.command = command;
 }

 public int getCommandLength() {
  return commandLength;
 }

 public void setCommandLength(int commandLength) {
  this.commandLength = commandLength;
 }

 @Override
 public String toString() {
  return "Request [encode=" + encode + ", command=" + command
    + ", commandLength=" + commandLength + "]";
 }
 
}

二、響應(yīng)協(xié)議的定義

協(xié)議的響應(yīng)主要包括:編碼、響應(yīng)內(nèi)容和響應(yīng)長度三個字段。

package com.binghe.params;

/**
 * 協(xié)議響應(yīng)的定義
 * @author binghe
 *
 */
public class Response {
 /**
  * 編碼
  */
 private byte encode;
 
 /**
  * 響應(yīng)內(nèi)容
  */
 private String response;
 
 /**
  * 響應(yīng)長度
  */
 private int responseLength;

 public Response() {
  super();
 }

 public Response(byte encode, String response, int responseLength) {
  super();
  this.encode = encode;
  this.response = response;
  this.responseLength = responseLength;
 }

 public byte getEncode() {
  return encode;
 }

 public void setEncode(byte encode) {
  this.encode = encode;
 }

 public String getResponse() {
  return response;
 }

 public void setResponse(String response) {
  this.response = response;
 }

 public int getResponseLength() {
  return responseLength;
 }

 public void setResponseLength(int responseLength) {
  this.responseLength = responseLength;
 }

 @Override
 public String toString() {
  return "Response [encode=" + encode + ", response=" + response
    + ", responseLength=" + responseLength + "]";
 }
 
}

三、編碼常量定義

編碼常量的定義主要包括UTF-8和GBK兩種編碼。

package com.binghe.constant;

/**
 * 常量類
 * @author binghe
 *
 */
public final class Encode {
 //UTF-8編碼
 public static final byte UTF8 = 1;
 //GBK編碼
 public static final byte GBK = 2;
}

四、客戶端的實現(xiàn)

客戶端先構(gòu)造一個request請求,通過Socket接口將其發(fā)送到遠(yuǎn)端,并接收遠(yuǎn)端的響應(yīng)信息,并構(gòu)造成一個Response對象。

package com.binghe.protocol.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import com.binghe.constant.Encode;
import com.binghe.params.Request;
import com.binghe.params.Response;
import com.binghe.utils.ProtocolUtils;

/**
 * 客戶端代碼
 * @author binghe
 *
 */
public final class Client {
 public static void main(String[] args) throws IOException{
  //請求
  Request request = new Request();
  request.setCommand("HELLO");
  request.setCommandLength(request.getCommand().length());
  request.setEncode(Encode.UTF8);
  
  Socket client = new Socket("127.0.0.1", 4567);
  OutputStream out = client.getOutputStream();
  
  //發(fā)送請求
  ProtocolUtils.writeRequest(out, request);
  
  //讀取響應(yīng)數(shù)據(jù)
  InputStream in = client.getInputStream();
  Response response = ProtocolUtils.readResponse(in);
  System.out.println("獲取的響應(yīng)結(jié)果信息為: " + response.toString());
 }
}

五、服務(wù)端的實現(xiàn)

服務(wù)端接收客戶端的請求,根據(jù)接收命令的不同,響應(yīng)不同的消息信息,如果是“HELLO”命令,則響應(yīng)“hello”信息,否則響應(yīng)“bye bye”信息。

package com.binghe.protocol.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.binghe.constant.Encode;
import com.binghe.params.Request;
import com.binghe.params.Response;
import com.binghe.utils.ProtocolUtils;

/**
 * Server端代碼
 * @author binghe
 *
 */
public final class Server {
 public static void main(String[] args) throws IOException{
  ServerSocket server = new ServerSocket(4567);
  while (true) {
   Socket client = server.accept();
   //讀取請求數(shù)據(jù)
   InputStream input = client.getInputStream();
   Request request = ProtocolUtils.readRequest(input);
   System.out.println("收到的請求參數(shù)為: " + request.toString());
   OutputStream out = client.getOutputStream();
   //組裝響應(yīng)數(shù)據(jù)
   Response response = new Response();
   response.setEncode(Encode.UTF8);
   if("HELLO".equals(request.getCommand())){
    response.setResponse("hello");
   }else{
    response.setResponse("bye bye");
   }
   response.setResponseLength(response.getResponse().length());
   ProtocolUtils.writeResponse(out, response);
  }
 }
}

六、ProtocolUtils工具類的實現(xiàn)

ProtocolUtilsreadRequest方法將從傳遞進(jìn)來的輸入流中讀取請求的encode、commandcommandLength三個參數(shù),進(jìn)行相應(yīng)的編碼轉(zhuǎn)化,構(gòu)造成Request對象返回。而writeResponse方法則是將response對象的字段根據(jù)對應(yīng)的編碼寫入到響應(yīng)的輸出流中。

有一個細(xì)節(jié)需要重點注意:OutputStream中直接寫入一個int類型,會截取其低8位,丟棄其高24位,所以,在傳遞和接收數(shù)據(jù)時,需要進(jìn)行相應(yīng)的轉(zhuǎn)化操作。

package com.binghe.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.binghe.constant.Encode;
import com.binghe.params.Request;
import com.binghe.params.Response;

/**
 * 協(xié)議工具類
 * @author binghe
 *
 */
public final class ProtocolUtils {
 /**
  * 從輸入流中反序列化Request對象
  * @param input
  * @return
  * @throws IOException
  */
 public static Request readRequest(InputStream input) throws IOException{
  //讀取編碼
  byte[] encodeByte = new byte[1];
  input.read(encodeByte);
  byte encode = encodeByte[0];
  
  //讀取命令長度
  byte[] commandLengthBytes = new byte[4];
  input.read(commandLengthBytes);
  int commandLength = ByteUtils.byte2Int(commandLengthBytes);
  
  //讀取命令
  byte[] commandBytes = new byte[commandLength];
  input.read(commandBytes);
  String command = "";
  if(Encode.UTF8 == encode){
   command = new String(commandBytes, "UTF-8");
  }else if(Encode.GBK == encode){
   command = new String(commandBytes, "GBK");
  }
  //組裝請求返回
  Request request = new Request(encode, command, commandLength);
  return request;
 }
 /**
  * 從輸入流中反序列化Response對象
  * @param input
  * @return
  * @throws IOException
  */
 public static Response readResponse(InputStream input) throws IOException{
  //讀取編碼
  byte[] encodeByte = new byte[1];
  input.read(encodeByte);
  byte encode = encodeByte[0];
  
  //讀取響應(yīng)長度
  byte[] responseLengthBytes = new byte[4];
  input.read(responseLengthBytes);
  int responseLength = ByteUtils.byte2Int(responseLengthBytes);
  
  //讀取命令
  byte[] responseBytes = new byte[responseLength];
  input.read(responseBytes);
  String response = "";
  if(Encode.UTF8 == encode){
   response = new String(responseBytes, "UTF-8");
  }else if(Encode.GBK == encode){
   response = new String(responseBytes, "GBK");
  }
  //組裝請求返回
  Response resp = new Response(encode, response, responseLength);
  return resp;
 }
 
 /**
  * 序列化請求信息
  * @param output
  * @param response
  */
 public static void writeRequest(OutputStream output, Request request) throws IOException{
  //將response響應(yīng)返回給客戶端
  output.write(request.getEncode());
  //output.write(response.getResponseLength());直接write一個int類型會截取低8位傳輸丟棄高24位
  output.write(ByteUtils.int2ByteArray(request.getCommandLength()));
  if(Encode.UTF8 == request.getEncode()){
   output.write(request.getCommand().getBytes("UTF-8"));
  }else if(Encode.GBK == request.getEncode()){
   output.write(request.getCommand().getBytes("GBK"));
  }
  output.flush();
 }
 /**
  * 序列化響應(yīng)信息
  * @param output
  * @param response
  */
 public static void writeResponse(OutputStream output, Response response) throws IOException{
  //將response響應(yīng)返回給客戶端
  output.write(response.getEncode());
  //output.write(response.getResponseLength());直接write一個int類型會截取低8位傳輸丟棄高24位
  output.write(ByteUtils.int2ByteArray(response.getResponseLength()));
  if(Encode.UTF8 == response.getEncode()){
   output.write(response.getResponse().getBytes("UTF-8"));
  }else if(Encode.GBK == response.getEncode()){
   output.write(response.getResponse().getBytes("GBK"));
  }
  output.flush();
 }
}

七、ByteUtils類的實現(xiàn)

package com.binghe.utils;

/**
 * 字節(jié)轉(zhuǎn)化工具類
 * @author binghe
 *
 */
public final class ByteUtils {
 /**
  * 將byte數(shù)組轉(zhuǎn)化為int數(shù)字
  * @param bytes
  * @return
  */
 public static int byte2Int(byte[] bytes){
  int num = bytes[3] & 0xFF;
  num |= ((bytes[2] << 8) & 0xFF00);
  num |= ((bytes[1] << 16) & 0xFF0000);
  num |= ((bytes[0] << 24) & 0xFF000000);
  return num;
 }
 
 /**
  * 將int類型數(shù)字轉(zhuǎn)化為byte數(shù)組
  * @param num
  * @return
  */
 public static byte[] int2ByteArray(int i){
  byte[] result = new byte[4];
  result[0]  = (byte)(( i >> 24 ) & 0xFF);
  result[1]  = (byte)(( i >> 16 ) & 0xFF);
  result[2]  = (byte)(( i >> 8 ) & 0xFF);
  result[3]  = (byte)(i & 0xFF);
  return result;
 }
}

到此這篇關(guān)于關(guān)于Java 實現(xiàn)Http協(xié)議詳細(xì)內(nèi)容的文章就介紹到這了,更多相關(guān)Java 實現(xiàn)Http協(xié)議內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Quartz觸發(fā)器CronTriggerBean配置用法詳解

    Java Quartz觸發(fā)器CronTriggerBean配置用法詳解

    這篇文章主要介紹了Java Quartz觸發(fā)器CronTriggerBean配置用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java TreeMap升序|降序排列和按照value進(jìn)行排序的案例

    Java TreeMap升序|降序排列和按照value進(jìn)行排序的案例

    這篇文章主要介紹了Java TreeMap升序|降序排列和按照value進(jìn)行排序的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • java簡單實現(xiàn)復(fù)制 粘貼 剪切功能代碼分享

    java簡單實現(xiàn)復(fù)制 粘貼 剪切功能代碼分享

    本文給大家分享了一段java編寫的簡單實現(xiàn)復(fù)制粘貼剪切功能的代碼,需要的小伙伴可以直接拿走使用。如有更好的方案,也可以告之本人。
    2014-11-11
  • Springboot傳輸數(shù)據(jù)時日期格式化問題

    Springboot傳輸數(shù)據(jù)時日期格式化問題

    這篇文章主要介紹了Springboot傳輸數(shù)據(jù)時日期格式化問題,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • MyBatis?Xml映射文件之字符串替換方式

    MyBatis?Xml映射文件之字符串替換方式

    這篇文章主要介紹了MyBatis?Xml映射文件之字符串替換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 新手Hadoop安裝 環(huán)境搭建

    新手Hadoop安裝 環(huán)境搭建

    這篇文章主要介紹了Hadoop的安裝與環(huán)境搭建教程圖解,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下,希望能給您帶來幫助
    2021-06-06
  • java訪問者模式的靜態(tài)動態(tài)及偽動態(tài)分派徹底理解

    java訪問者模式的靜態(tài)動態(tài)及偽動態(tài)分派徹底理解

    這篇文章主要為大家介紹了java訪問者模式的靜態(tài)動態(tài)及偽動態(tài)分派徹底理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Java Spring AOP詳解

    Java Spring AOP詳解

    這篇文章主要介紹了Java的Spring框架中的AOP實現(xiàn)實例,AOP面向切面編程其實也可以被看作是一個設(shè)計模式去規(guī)范項目的結(jié)構(gòu),需要的朋友可以參考下
    2021-09-09
  • 通過實例講解springboot整合WebSocket

    通過實例講解springboot整合WebSocket

    這篇文章主要介紹了通過實例講解springboot整合WebSocket,WebSocket為游覽器和服務(wù)器提供了雙工異步通信的功能,即游覽器可以向服務(wù)器發(fā)送消息,服務(wù)器也可以向游覽器發(fā)送消息。,需要的朋友可以參考下
    2019-06-06
  • JAVA實現(xiàn)微信APPV3支付保姆級教程

    JAVA實現(xiàn)微信APPV3支付保姆級教程

    微信實現(xiàn)支付功能與支付寶實現(xiàn)支付功能是相似的,這篇文章主要介紹了JAVA實現(xiàn)微信APPV3支付的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01

最新評論