原文链接: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. Wireshark无法解析OpenFlow配置协议 解决方法

    在使用wireshark对OpenFlow交换机与FlowVisor的通信过程进行抓包分析的时候,在其选项中有openflow_v1选项,但Wireshark竟无法解析OpenFlow协议. 在查阅相 ...

  2. BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1003 题意: 思路: 首先用spfa计算一下任意两天之内的最短路,dis[a][b]表示的就是在第a ...

  3. Python matplot画柱状图(一)

    图的存在,让数据变得形象化.无论多么复杂的东西,都是简单的组合. import matplotlib.pyplot as plt import numpy as np dict = {'A': 40, ...

  4. Python中浮点数精度处理

    Python中,浮点数运算,经常会碰到如下情况: 出现上面的情况,主要还是因浮点数在计算机中实际是以二进制保存的,有些数不精确.比如说: 0.1是十进制,转化为二进制后它是个无限循环的数:0.0001 ...

  5. html 居中的内容显示框

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. [原][OSG]深入osg函数----SceneView::cull 函数

    参考:最长一帧 先介绍几个类: osgUtil::CullVisitor:“筛选访问器” 当我们使用它遍历场景图形的各个节点时, CullVisitor 将会对每一个遇到的节点执行场景筛选的工作,判断 ...

  7. Codeforces 140D - New Year Contest

    140D - New Year Contest 思路:贪心+排序.罚时与时间成正比,因为在0点前做完的题都可以在0点提交.从时间短的开始做最优. 代码: #include<bits/stdc++ ...

  8. 记录Vmware Workstation及Centos6.8 的安装

    网上找到的一个非常详细的安装详解.个人觉得非常好.于是加保存一下.地址:http://www.mamicode.com/info-detail-1462939.html

  9. oracle创建/删除表空间、创建/删除用户并赋予权限

    创建表空间 分开执行如下sql语句 --创建临时表空间 CREATE SMALLFILE TEMPORARY TABLESPACE "TEMP11" TEMPFILE 'E:\ap ...

  10. JPA、SpringData JPA 、Hibernate和Mybatis 的区别和联系

    一.JPA 概述 1. Java Persistence API(Java 持久层 API):用于对象持久化的 API 2. 作用:使得应用程序以统一的方式访问持久层 3. 前言中提到了 Hibern ...