Java Socket 实现HTTP服务器核心
原文链接: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服务器核心的更多相关文章
- 实现服务器和客户端数据交互,Java Socket有妙招
摘要:在Java SDK中,对于Socket原生提供了支持,它分为ServerSocket和Socket. 本文分享自华为云社区<Java Socket 如何实现服务器和客户端数据交互>, ...
- JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo
OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...
- java 网络编程 TCP协议 java 服务器和客户端 java socket编程
一个 HelloWord 级别的 Java Socket 通信的例子.通讯过程: 先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求.然后运行 Client 端,客 ...
- 使用Java Socket手撸一个http服务器
原文连接:使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomc ...
- 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)
在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...
- JAVA Socket连接服务器时可能抛出的异常
1.UnknownHostException:host(非ip)无法识,就会报该异常,www.google.com.hk这个虽然也ping不通,但是不会报该错,因为他是一个确实存在的域名.他会报Con ...
- java socket 服务器多线程 数据转发的研究实践
项目中借鉴了以下资料: https://www.cnblogs.com/whenever/p/5526420.html https://www.cnblogs.com/jpwz/p/5715852.h ...
- Java Socket编程如何建立两者关系
转自:http://developer.51cto.com/art/201003/190582.htm Java Socket编程需要大家详细的学习,有关的技术一直在不断的更新.那么要如何才能掌握好有 ...
- JAVA通信系列一:Java Socket技术总结
本文是学习java Socket整理的资料,供参考. 1 Socket通信原理 1.1 ISO七层模型 1.2 TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...
随机推荐
- 论文笔记——NEURAL ARCHITECTURE SEARCH WITH REINFORCEMENT LEARNING
论文地址:https://arxiv.org/abs/1611.01578 1. 论文思想 强化学习,用一个RNN学一个网络参数的序列,然后将其转换成网络,然后训练,得到一个反馈,这个反馈作用于RNN ...
- html5标签 H5标签
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"& ...
- UVa 225 黄金图形(回溯+剪枝)
https://vjudge.net/problem/UVA-225 题意:平面上有k个障碍点,从(0,0)出发,第一次走1个单位,第二次走2个单位,...第n次走n个单位,最后恰好回到(n,n).每 ...
- php五大运行模式CGI,FAST-CGI,CLI,ISAPI,APACHE模式
做 php 开发的应该都知道 php 运行模式概念吧,本文将要和大家分享的是关于php目前比较常见的五大运行模式:包括cgi .fast-cgi.cli.isapi.apache模块的DLL ,下面作 ...
- jdk、tomcat、solr环境搭建
环境概述 1)操作系统:windows7旗舰版(64位) 2)jdk:jdk-8u131-windows-x64: 3)tomcat:apache-tomcat-9.0.0.M21 4)solr:so ...
- go 修改字符串
在Go中字符串是不可变的,例如下面的代码编译时会报错:cannot assign to s[] var s string = "hello" s[] = 'c' 但如果真的想要修改 ...
- python 元组转字符串
tup = ('e', 'x', 'e', 'r', 'c', 'i', 's', 'e', 's') str = ''.join(tup) print(str)
- python profile性能分析
#! /usr/bin/env python # encoding=utf8 import profile def func1(): for i in range(1000): pass def fu ...
- chrome的url列表里面也找不到chrome://plugins的原因
plugins 页面被移除后,可以访问: chrome://settings/content 调整 Flash.PDF 的设置. 原本 plugins 页面就基本只剩下这两货了,移除掉确实没啥影响. ...
- URLConnection和HttpClient使用入门
本讲内容:URLConnection和HttpClient使用入门 在 Android中除了使用WebView控件访问网络以外,还有用代码方式访问网络的方法,代码方式有时候会显得更加灵活.本讲会介绍使 ...