一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 使用 Java 類 實現Http協議

使用 Java 類 實現Http協議

2021-12-21 13:43冰 河 Java教程

這篇文章主要介紹了用幾個Java類簡單的實現了Http協議相關資料,感興趣的的朋友可以參考下面具體的文章內容

Java 實現Http協議

HTTP協議屬于應用層協議,它構建于TCP和IP協議之上,處于TCP/IP協議架構層的頂端,所以,它不用處理下層協議間諸如丟包補發、握手及數據的分段及重新組裝等繁瑣的細節,使開發人員可以專注于應用業務。

協議是通信的規范,為了更好的理解HTTP協議,我們可以基于Java的Socket API接口,通過設計一個簡單的應用層通信協議,來簡單分析下協議實現的過程和細節。

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

我們接下來用Java實現這個簡單的應用層通信協議,

使用 Java 類 實現Http協議

一、協議請求的定義

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.binghe.params;
/**
 * 協議請求的定義
 * @author binghe
 *
 */
public class Request {
 /**
  * 協議編碼
  */
 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 + "]";
 }
 
}

二、響應協議的定義

協議的響應主要包括:編碼、響應內容和響應長度三個字段。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.binghe.params;
 
/**
 * 協議響應的定義
 * @author binghe
 *
 */
public class Response {
 /**
  * 編碼
  */
 private byte encode;
 
 /**
  * 響應內容
  */
 private String response;
 
 /**
  * 響應長度
  */
 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兩種編碼。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

四、客戶端的實現

客戶端先構造一個request請求,通過Socket接口將其發送到遠端,并接收遠端的響應信息,并構造成一個Response對象。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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();
  
  //發送請求
  ProtocolUtils.writeRequest(out, request);
  
  //讀取響應數據
  InputStream in = client.getInputStream();
  Response response = ProtocolUtils.readResponse(in);
  System.out.println("獲取的響應結果信息為: " + response.toString());
 }
}

五、服務端的實現

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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();
   //讀取請求數據
   InputStream input = client.getInputStream();
   Request request = ProtocolUtils.readRequest(input);
   System.out.println("收到的請求參數為: " + request.toString());
   OutputStream out = client.getOutputStream();
   //組裝響應數據
   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工具類的實現

ProtocolUtilsreadRequest方法將從傳遞進來的輸入流中讀取請求的encodecommandcommandLength三個參數,進行相應的編碼轉化,構造成Request對象返回。而writeResponse方法則是將response對象的字段根據對應的編碼寫入到響應的輸出流中。

有一個細節需要重點注意:OutputStream中直接寫入一個int類型,會截取其低8位,丟棄其高24位,所以,在傳遞和接收數據時,需要進行相應的轉化操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;
 
/**
 * 協議工具類
 * @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];
  
  //讀取響應長度
  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響應返回給客戶端
  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();
 }
 /**
  * 序列化響應信息
  * @param output
  * @param response
  */
 public static void writeResponse(OutputStream output, Response response) throws IOException{
  //將response響應返回給客戶端
  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類的實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.binghe.utils;
 
/**
 * 字節轉化工具類
 * @author binghe
 *
 */
public final class ByteUtils {
 /**
  * 將byte數組轉化為int數字
  * @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類型數字轉化為byte數組
  * @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;
 }
}

到此這篇關于關于Java 實現Http協議詳細內容的文章就介紹到這了,更多相關Java 實現Http協議內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

使用 Java 類 實現Http協議

原文鏈接:https://blog.csdn.net/l1028386804/article/details/117154518

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
主站蜘蛛池模板: 国内永久第一免费福利视频 | 12一14性xxxxx国外 | 暖暖的韩国免费观看 | 农夫色综合 | segui久久综合精品 | 日韩精品高清自在线 | 国产福利资源网在线观看 | 男人在线网址 | 青青热久久综合网伊人 | 国产成人久久精品一区二区三区 | 办公室操秘书 | 日本老妇乱子伦中文视频 | 国产理论片在线观看 | 亚洲不卡视频 | chinesegay黑袜玩奴 | 草莓视频网站18勿进 | 99re在线精品视频免费 | 色戒完整版 | girlfriend动漫在线播放 | 无码人妻99久久密AV | 日本黄a | 国产99青草全福视在线 | 性趣味商品推荐 | 91桃花| 大胆私拍模特国模377 | 五月一区二区久久综合天堂 | 精品手机在线1卡二卡3卡四卡 | 青草园网站在线观看 | 成人免费淫片95视频观看网站 | 91热国内精品永久免费观看 | 奇米影视亚洲狠狠色 | 精品视频在线观看免费 | 5g996未满十八 | 亚洲精品一区二区三区中文字幕 | 激情偷拍网 | 亚洲精品αv一区二区三区 亚洲精品91大神在线观看 | 精品无人区一区二区三区 | 日本aaaaa高清免费看 | 亚洲欧美成人综合在线 | 午夜国产精品福利在线观看 | 91色视 |