原文链接:http://www.ihuxu.com/p/235.html

 

首先了解下HTTP协议:

wikiPedia的说明很好,在此不重复了。链接:http://zh.wikipedia.org/wiki/Http

源码分析:

概述:此两个代码段,完成服务器监听,线程处理短请求服务和应答(符合伪HTTP协议,“伪”即判断协议格式不严谨)。展示了利用java socket完成http通信的核心原理代码,希望给初次学习socket或者第一次利用java来实现HTTP协议服务器的朋友提供些帮助。

利用 Java Socket 网络编程来绑定服务器某个端口进行监听。

 1 package JHServer;
2
3 import java.io.IOException;
4 import java.net.ServerSocket;
5 import java.net.Socket;
6
7 public class Server {
8
9 private static int PORT = 1720;
10 public static String charset = "utf-8";
11 private ServerSocket ss;
12 private Socket client;
13
14 public static void main(String[] args) {
15 new Server();
16 }
17
18 public Server() {
19 try {
20 this.ss = new ServerSocket(this.PORT);
21 System.out.println("Server Listening Port " + this.PORT + "...");
22 boolean isGo = true;
23 while(isGo){
24 this.client = this.ss.accept();
25 System.out.println("One Client Connected. " + this.client);
26 ClientThread ct = new ClientThread(this.client);
27 Thread t = new Thread(ct);
28 t.start();
29 System.out.println("One Client Thread Already Started...");
30 }
31 } catch (IOException e) {
32 e.printStackTrace();
33 } finally {
34 try{
35 if(this.ss != null){
36 this.ss.close();
37 this.ss = null;
38 }
39 if(this.client != null){
40 this.client.close();
41 this.client = null;
42 }
43 } catch(IOException e) {
44 e.printStackTrace();
45 }
46 }
47 }
48
49 }

说明:上述代码完成了服务端口(1720,你懂么)的监听,并同时利用线程了处理每个客户端(Client )的消息请求,以减少服务器处理”短请求“阻塞问题。

下述代码完成请求是否符合伪HTTP协议,并完成响应消息。

  1 package JHServer;
2
3 import java.io.*;
4 import java.net.Socket;
5 import java.util.Date;
6
7 import action.ManagerEachMatchInfo;
8
9 import view.*;
10
11 public class ClientThread implements Runnable {
12
13 private float requestDelay = (float)0.5;//
14
15 private Socket _s;
16 private BufferedReader i;
17 private PrintStream o;
18
19 public ClientThread(Socket s) {
20 this._s = s;
21 }
22
23 public void run() {
24 try {
25 this.i = new BufferedReader(new InputStreamReader(this._s.getInputStream()));
26 this.o = new PrintStream(this._s.getOutputStream());
27
28 String request = this.getValidRequest();
29
30 if( !request.equals("") ) {
31 System.out.print("当前虚拟机最大可用内存为:");
32 System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");
33 System.out.print("当前,虚拟机已占用内存:");
34 System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");
35 this.o.println("HTTP/1.1 200 OK");
36 Date now = new Date();
37 this.o.println("Data:" + now);
38 this.o.println("Server: JHServer");
39 this.o.println("Access-Control-Allow-Origin:*");
40
41 this.o.println("Content-Type: text/html; charset=UTF-8");
42 this.o.println();
43 String content = null;
44 IndeMatchInfo imi = new IndeMatchInfo(22,22,2,2,22,(double)0.0,"S7-200");
45 content = imi.getHTML();
46
47 imi.clear();
48 imi = null;
49 System.out.print("当前虚拟机最大可用内存为:");
50 System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");
51 System.out.print("当前,虚拟机已占用内存:");
52 System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");
53
54 this.o.println(content);
55 content = "";
56 this.o.flush();
57
58 }
59
60 } catch (IOException e) {
61 e.printStackTrace();
62 } finally {
63 this.close();
64 }
65
66 }
67
68 private String getValidRequest() {
69
70 float second = (float) 0.0;
71 boolean isGo = true;
72 String request = null;
73 try {
74 while (!this.i.ready()) {
75 second += 0.01;
76 if (second > this.requestDelay) {
77 System.out.println("One Client Delayed " + this._s);
78 isGo = false;
79 break;
80 }
81 Thread.sleep(10);
82 }
83
84 if (isGo == true) {
85 request = this.i.readLine();
86 if( request.contains("GET /") && request.contains(" HTTP/") ) {
87 request = request.substring(request.indexOf("/"),request.indexOf(" HTTP/"));
88 System.out.println("Client Request Info: " + request);
89 } else {
90 isGo = false;
91 }
92 }
93 } catch (InterruptedException e) {
94 e.printStackTrace();
95 } catch (IOException e) {
96 e.printStackTrace();
97 } finally {
98 if(isGo == true) {
99 return request;
100 } else {
101 return "null";
102 }
103 }
104 }
105
106 private void close() {
107 try {
108 if (this.i != null) {
109 this.i.close();
110 this.i = null;
111 }
112 if (this.o != null) {
113 this.o.close();
114 this.o = null;
115 }
116 if (this._s != null) {
117 this._s.close();
118 this._s = null;
119 }
120 System.out.println("One Client Disconnected...");
121 } catch (IOException e) {
122 e.printStackTrace();
123 }
124 }
125
126 }

说明:

1、getValidRequest() 验证请求消息是否满足伪HTTP协议。比如:GET /images/logo.gif HTTP/1.1,则会返回"/images/logo.gif"。若不符合伪HTTP协议或者请求时不发送任何消息头(比如通过telnet访问,此情况最大延迟0.5秒),则会返回空串。

2、close(),释放内存,同时线程结束。

3、run(),短请求的线程主体,在此处可以进行数据逻辑处理,并返回特定消息内容。

Java Socket 实现HTTP服务器核心的更多相关文章

  1. 实现服务器和客户端数据交互,Java Socket有妙招

    摘要:在Java SDK中,对于Socket原生提供了支持,它分为ServerSocket和Socket. 本文分享自华为云社区<Java Socket 如何实现服务器和客户端数据交互>, ...

  2. JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo

    OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...

  3. java 网络编程 TCP协议 java 服务器和客户端 java socket编程

    一个 HelloWord 级别的 Java Socket 通信的例子.通讯过程:        先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求.然后运行 Client 端,客 ...

  4. 使用Java Socket手撸一个http服务器

    原文连接:使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomc ...

  5. 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)

    在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...

  6. JAVA Socket连接服务器时可能抛出的异常

    1.UnknownHostException:host(非ip)无法识,就会报该异常,www.google.com.hk这个虽然也ping不通,但是不会报该错,因为他是一个确实存在的域名.他会报Con ...

  7. java socket 服务器多线程 数据转发的研究实践

    项目中借鉴了以下资料: https://www.cnblogs.com/whenever/p/5526420.html https://www.cnblogs.com/jpwz/p/5715852.h ...

  8. Java Socket编程如何建立两者关系

    转自:http://developer.51cto.com/art/201003/190582.htm Java Socket编程需要大家详细的学习,有关的技术一直在不断的更新.那么要如何才能掌握好有 ...

  9. JAVA通信系列一:Java Socket技术总结

    本文是学习java Socket整理的资料,供参考. 1       Socket通信原理 1.1     ISO七层模型 1.2     TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...

随机推荐

  1. ftp协议及vsftpd的基本应用

    1.ftp协议及vsftpd的基本应用 vsftpd 是"very secure FTP daemon"的缩写,安全性是它的一个最大的特点.vsftpd 是一个 UNIX 类操作系 ...

  2. HDU 5884 Sort(二分+优先队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=5884 题意:有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和.现在另外一个屌丝要 ...

  3. UVa 147 Dollars(完全背包)

    https://vjudge.net/problem/UVA-147 题意: 换零钱,计算方案数. 思路: 完全背包,UVa674的加强版. #include<iostream> #inc ...

  4. Elasticsearch 多字段搜索

    查询很少是对一个字段做 match 查询,通常都是一个 query 查询多个字段,比如一个 doc 有 title.content.pagetag 等文本字段,要在这些字段查询含多个 term 的 q ...

  5. 《剑指offer》第二十二题(链表中倒数第k个结点)

    // 面试题22:链表中倒数第k个结点 // 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯, // 本题从1开始计数,即链表的尾结点是倒数第1个结点.例如一个链表有6个结点, ...

  6. 使用Fragment适应不同屏幕和分辨率

    Fragment是Android3.0后增加的新控件,有点类似于Activity组件,也是用来承载各种View元素.Google增加这个 玩意的目的是为了平板电脑里面可以复用部分显示的View,只要写 ...

  7. 缓存地图 ArcGIS ——Local compact and exploded tile cache layer for WPF API

      ArcGISArcGIS 主页 特色 合约 图库 地图 组 帮助 我的内容 我的组织 登录 我的个人资料 帮助 管理员指南 登出 0 搜索全部内容 搜索地图 搜索图层 搜索应用程序 搜索工具 搜索 ...

  8. 20170528xlVBA凑数一例

    Public Sub MakeUp() Dim Sht As Worksheet Set Sht = ThisWorkbook.Worksheets("设置") Dim Total ...

  9. 安装 tensorflow 时遇到 OSError: [Errno 1] Operation not permitted 的解决办法

    Installing collected packages: numpy, scipy, six, pyyaml, Keras, opencv-python, h5py, html5lib, blea ...

  10. Python在七牛云平台的应用(三)简单的人脸识别

    前言 这是最后一篇介绍python在七牛云平台的应用了,因为-前两篇文章第一篇分享了怎么安装七牛的官方库以及怎么对自己的空间进行下载上传,删除等行动.而第二篇则分享了怎么利用七牛的API接口,由于七牛 ...