原文链接: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. 论文笔记——Channel Pruning for Accelerating Very Deep Neural Networks

    论文地址:https://arxiv.org/abs/1707.06168 代码地址:https://github.com/yihui-he/channel-pruning 采用方法 这篇文章主要讲诉 ...

  2. 抽象类的继承,接口的实现,接口类型数组的使用,根据instanceof判断(返回)是否该是哪一个类型,类型的强转.

    总觉得之前第2处有点问题,果然. 还需要instanceof判定一下,然后还需要把数组Animal[]转为Pet的才有方法play()~~~!

  3. 以QQ举例 说明计算机网络中的一些概念区别(TCP与UDP,广播与单播)

    QQ 中的 广播与单播 今天简单地学习了一下 广播和多播(组播) 的知识.关于 单播和多播 的概念,可以用 QQ 中的一些例子来解释. 单播,就像 两个人聊QQ 一样,信息的接收和传递只在两个节点之间 ...

  4. samba基本应用24-4及示例

    samba smb:service message block(137/udp, 138/udp, 139/tcp, 445/tcp) 协议是:CIFS:Common Internet File Sy ...

  5. 对Tomcat启动或运行时,项目对jar包依赖路径的一些粗浅认知

    Tomcat在运行webapp项目的时候,需要各种依赖jar包.它会从2个地方去找这些包 1.Tomcat自己的lib目录中 2.webapp目录下,webapps\{项目}\WEB-INF\lib ...

  6. poj 1523 SPF 无向图求割点

    SPF Description Consider the two networks shown below. Assuming that data moves around these network ...

  7. Selenium 对元素element的操作举例

    前三个用的比较多,模拟用户操作最多的就是点击,输入文本,其他的UI自动化测试中涉及的不多,对判断元素是否存在,断言元素是否被选中,元素被选中后CSS属性是否更改等,还是很有必要的.

  8. Beta 冲刺 第三天

    第三天 2018.6.26 今日完成任务情况. 妥志福.牛瑞鑫: 完成任务:让用户接触系统,指出系统中存在的问题,并统计修改的问题,提出修改的方案. 王胜海.马中林: 完成任务:对文档中存在的问题修改 ...

  9. js 中的几个假值

    1. 使用场景 if分支语句   /  短路语句while循环语句for里的第二个语句 2. 6个假值 (都属于 原始类型数据的一部分内容,非原始类型即对象都是真值,如:对象.数组.正则.函数   . ...

  10. 个人学期总结及Python+Flask+MysqL的web建设技术过程

    一个学期即将过去,我们也迎来了2018年.这个学期,首次接触了web网站开发建设,不仅是这门课程,还有另外一门用idea的gradle框架来制作网页. 很显然,用python语言的flask框架更加简 ...