`

http - simple server & client

 
阅读更多

Simple http server & client implementation by pure j2se.

 

http - client:

package eric.j2se.net.http;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * <p>
 * A simple http client.
 * </p>
 * 
 * @author eric
 * @date Jan 6, 2014 4:29:54 PM
 */
public class SimpleHttpClient {
	/**
	 * send http request & get response,
	 * 
	 * @param host
	 *            hostname or ip
	 * @param path
	 *            path after host, format: "/xxx"
	 * @param port
	 * @return response string
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static String httpRequest(String host, String path, int port) throws IOException, InterruptedException {
		Socket client = new Socket(host, port);
		StringBuffer requestInfo = new StringBuffer("");
		StringBuffer responseInfo = new StringBuffer("");

		// prepare request info,
		requestInfo.append("GET " + path + " HTTP/1.1\n");
		requestInfo.append("Host: " + host + "\n");
		requestInfo.append("Connection: Close\n");

		// send request,
		PrintWriter pw = new PrintWriter(client.getOutputStream(), true);
		pw.println(requestInfo.toString());
		System.out.println("****** request - start ******");
		System.out.println(requestInfo.toString());
		System.out.println("****** request - end ******");

		// get response info,
		LineNumberReader lnr = new LineNumberReader(new InputStreamReader(client.getInputStream()));
		String line;
		while ((line = lnr.readLine()) != null) {
			responseInfo.append(line + "\n");
		}
		System.out.println("****** response - start ******");
		System.out.println(responseInfo.toString());
		System.out.println("****** response - end ******");

		pw.close();
		lnr.close();
		client.close();
		return responseInfo.toString();
	}

	/****** test - start ******/
	/**
	 * test http request,
	 */
	public static void testHttpRequest() {
		try {
			httpRequest("localhost", "/index.html", 80);
			// sendRequest("www.google.com.hk", "/", 80);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

	}
	/****** test - end ******/
}

 

 

http - server:

package eric.j2se.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * <p>
 * A simple http server.
 * </p>
 * 
 * @author eric
 * @date Jan 9, 2014 10:10:48 PM
 */
public interface HttpServer {
	/**
	 * start server,
	 */
	void start();

	/**
	 * parse, get params,
	 * 
	 * @param is
	 * @return params
	 * @throws IOException
	 */
	Map<String, String> parse(InputStream is) throws IOException;

	/**
	 * read param from param string,
	 * 
	 * @param paramStr
	 *            params string, format: name1=value1&name2=value2\
	 * @param isBody
	 *            whether the params from body,
	 * 
	 * @return map of param key/value,
	 */
	Map<String, String> parseParam(String paramStr, boolean isBody);

	/**
	 * send response
	 * 
	 * @param os
	 * @param paramMap
	 */
	void response(OutputStream os, Map<String, String> paramMap);

	/**
	 * shutdown server,
	 * 
	 * @throws IOException
	 */
	void terminate() throws IOException;
}

 

package eric.j2se.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

/**
 * <p>
 * A simple http server implementation.
 * </p>
 * TODO ... add more feature
 * 
 * @author eric
 * @date Jan 10, 2014 2:53:50 AM
 */
public class SimpleHttpServer implements HttpServer {
	private ServerSocket server;

	public SimpleHttpServer(int port, int backlog, String host) throws UnknownHostException, IOException {
		server = new ServerSocket(port, backlog, InetAddress.getByName(host));
	}

	@Override
	public void start() {
		Socket socket = null;
		InputStream inStream = null;
		OutputStream outStream = null;

		Map<String, String> paramMap = null;

		while (true) {
			try {
				socket = server.accept();

				// get input
				inStream = socket.getInputStream();
				paramMap = parse(inStream);
				// paramMap = new HashMap();

				// write output
				outStream = socket.getOutputStream();
				response(outStream, paramMap);

				// close socket, this indicate the client that the response is finished,
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (inStream != null) {
						inStream.close();
					}
					if (outStream != null) {
						outStream.close();
					}
					if (socket != null) {
						socket.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public Map<String, String> parse(InputStream is) throws IOException {
		Map<String, String> paramMap = new HashMap<String, String>();
		LineNumberReader lr = new LineNumberReader(new InputStreamReader(is));
		String inputLine = null;
		String method = null;
		String httpVersion = null;
		String uri = null;

		// read request line
		inputLine = lr.readLine();
		String[] requestCols = inputLine.split("\\s");
		method = requestCols[0];
		uri = requestCols[1];
		httpVersion = requestCols[2];
		System.out.println("http version:\t" + httpVersion);

		// parse GET param
		if (uri.contains("?")) {
			paramMap.putAll(parseParam(uri.split("\\?", 2)[1], false));
		}

		// read header
		while (StringUtils.isNotBlank(inputLine = lr.readLine())) {
			System.out.println("post header line:\t" + inputLine);
		}

		// read body - POST method
		if (method.toUpperCase().equals("POST")) {
			StringBuffer bodySb = new StringBuffer();
			char[] bodyChars = new char[1024];
			int len;

			// ready() make sure it will not block,
			while (lr.ready() && (len = lr.read(bodyChars)) > 0) {
				bodySb.append(bodyChars, 0, len);
			}
			paramMap.putAll(parseParam(bodySb.toString(), true));

			System.out.println("post body:\t" + bodySb.toString());
		}

		return paramMap;
	}

	@Override
	public Map<String, String> parseParam(String paramStr, boolean isBody) {
		String[] paramPairs = paramStr.trim().split("&");
		Map<String, String> paramMap = new HashMap<String, String>();

		String[] paramKv;
		for (String paramPair : paramPairs) {
			if (paramPair.contains("=")) {
				paramKv = paramPair.split("=");
				if (isBody) {
					// replace '+' to ' ', because in body ' ' is replaced by '+' automatically when post,
					paramKv[1] = paramKv[1].replace("+", " ");
				}
				paramMap.put(paramKv[0], paramKv[1]);
			}
		}

		return paramMap;
	}

	@Override
	public void response(OutputStream os, Map<String, String> paramMap) {
		String name = StringUtils.isBlank(paramMap.get("name")) ? "xxx" : paramMap.get("name");

		PrintWriter pw = null;
		pw = new PrintWriter(os);
		pw.println("HTTP/1.1 200 OK");
		pw.println("Content-type: text/html; Charset=UTF-8");
		pw.println("");
		pw.println("<h1>Hi <span style='color: #FFF; background: #000;'>" + name + "</span> !</h1>");
		pw.println("<h4>current date: " + new Date() + "</h4>");
		pw.println("<p>you can provide your name via a param called <span style='color: #F00; background: yellow;'>\"name\"</span>, in both GET and POST method.</p>");
		pw.flush();
	}

	@Override
	public void terminate() throws IOException {
		server.close();
	}

	/****** test - start ******/
	public static void main(String[] args) {
		testHttpServer();
	}

	// test http server,
	public static void testHttpServer() {
		try {
			HttpServer server = new SimpleHttpServer(9090, 1, "localhost");
			server.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/****** test - end ******/
}

 

 

分享到:
评论

相关推荐

    android--simple-Server-and-Client.rar_Server_android_android cli

    "android--simple-Server-and-Client.rar" 提供了一个示例,让我们来深入探讨这个主题。 1. **Android 服务器搭建**: - **Socket编程**:在Android中,服务器端通常使用Java的Socket类来创建TCP连接。通过...

    simple-tcp-client-server.zip_C# TCP server_client server_simple_

    本项目“simple-tcp-client-server”提供了一个C#实现的简单TCP客户端与服务器的示例,旨在帮助开发者理解和实践TCP通信的基本原理。 首先,我们来探讨TCP服务器。在C#中,可以使用System.Net.Sockets命名空间中的...

    leetcode答案-oauth-server-simple-example:oauth-server-simple-example

    Client Identifier +-------+-------+ | -+----(A)-- & Redirection URL ----&gt;| | | User- | | Authorization | | Agent -+----(B)-- User authenticates ---&gt;| Server | | | | | | -+----(C)-- Authorization...

    一个简单的IOCP服务器/客户端类

    - Server类:包含IOCP服务器的实现,包括初始化、监听、接收连接和处理I/O请求等功能。 - Client类:包含IOCP客户端的实现,包括连接服务器、发送和接收数据等操作。 - 工作线程代码:用于处理完成端口中的I/O...

    Android代码-simple-rtc-client-android

    서버 : simple-rtc-signaling-server setting 서버 주소를 G.kt파일에서 수정. val SIGNAL_SERVER_ADDR = "ws://192.168.35.192:12345" MVVM Notify 방법은 RxJava를 이용 Dependency Injection Kodein 이용

    mysql-community-server-5.7.28-x86.tar.gz

    perl-HTTP-Tiny-0.033-3.el7.noarch.rpm perl-libs-5.16.3-294.el7_6.x86_64.rpm perl-macros-5.16.3-294.el7_6.x86_64.rpm perl-parent-0.225-244.el7.noarch.rpm perl-PathTools-3.40-5.el7.x86_64.rpm perl-Pod-...

    onvif-qt-server-client-master_onviflib_QtServer_onvifqt_zip_onvi

    总之,"onvif-qt-server-client-master"这个项目为开发者提供了构建ONVIF服务器和客户端的工具,通过QtServer和Onvifqt,开发者可以快速地实现ONVIF设备的管理和控制,提升监控系统的集成度和兼容性。通过深入研究和...

    《A Simple IOCP Server/Client Class》

    本文将基于《A Simple IOCP Server/Client Class》这一项目,深入探讨IOCP的基本概念、工作原理以及如何在实际编程中应用。** **一、IOCP基础** 1. **什么是IOCP** IOCP,全称Input/Output Completion Port,是一...

    JAVA-Simple-Echo-Client-Server

    在"JAVA-Simple-Echo-Client-Server"项目中,开发者使用了Java语言,这是一门广泛应用于企业级应用、移动应用和云计算平台的编程语言。Java的强项在于其跨平台性,由于“一次编写,到处运行”的特性,使得Java成为...

    qpid-cpp-server

    5. `cyrus-sasl-lib-2.1.26-23.el7.x86_64.rpm`、`cyrus-sasl-2.1.26-23.el7.x86_64.rpm`:Cyrus SASL(Simple Authentication and Security Layer)库,提供身份验证服务,支持多种认证机制,对于安全的网络通信至...

    Simple Client-Server Demo.rar_DEMO_Server_server client_客户服务器

    这个"Simple Client-Server Demo"就是一个展示这种模式的示例。在这个压缩包中,包含了一个简单的客户端和服务器端的代码,以及一个可能是提供下载来源信息的文本文件"www.pudn.com.txt"。 客户端-服务器架构的核心...

    nekoq-simple-client

    "nekoq-simple-client"是一个基于Java开发的轻量级客户端库,专为连接到github.com/moetang-arch/nekoq/tcp/queue server设计。这个库简化了与queue服务器交互的过程,使得开发者能够更方便地在Java应用程序中实现...

    java-simple-server-client:带有 DataInputOutputStreams 的简单服务器-客户端协议程序

    来自教程 Java Networking :: Simple server-client protocol program with DataInput/OutputStreams! 一个第一和第二终端 java Session

    spring-boot-websocket-client代码示例

    Spring Boot提供了一套完整的WebSocket支持,包括Stomp(Simple Text Oriented Messaging Protocol)子协议,这使得在WebSocket上进行消息传递变得更加容易。WebSocket API允许开发者创建高效、低延迟的实时应用,如...

    Simple-Web-Server:使用C ++ 11和Boost.Asio实现的非常简单,快速,多线程,独立于平台的HTTP和HTTPS服务器和客户端库。 创建是使REST资源可从C ++应用程序获得的简单方法

    《基于C++11与Boost.Asio的Simple-Web-Server:构建HTTP与HTTPS服务器与客户端库》 在IT行业中,高效、灵活的网络通信库是开发者的重要工具。Simple-Web-Server是一款由C++11语言标准和Boost.Asio库实现的轻量级、...

    Android代码-RTSP-Client-Server

    RTSP-Client-Server Introduction Streaming videos are ubiquitous in the web today. The internet, originally designed for simple text/document based transfers using protocols such as the HTTP, is the ...

    Simple Client-server Interactions using C#

    Simple Client-server Interactions using C# By BobJanova C#封装的简单的客户机/服务器Socket通讯程序,非常棒!

    seata-server-2.0.0.zip

    Seata(Simple Extensible Autonomous Transaction Architecture)是一款开源的分布式事务解决方案,主要致力于提供高性能和简单易用的分布式事务服务。Seata将ACID(原子性、一致性、隔离性、持久性)事务特性扩展...

    seata-server-0.9.0.RELEASE.zip

    5. **客户端集成**:在你的应用代码中,需要引入Seata的客户端SDK(如Java的`seata-client`),并配置事务服务中心的地址,以便客户端在执行分布式事务时能与Seata-server通信。 6. **使用Seata提供的事务模式**:...

    Simple Client-Server Demo 简单的客户端服务器模型

    这个"Simple Client-Server Demo"就是一个简单的示例,它使用C语言实现了基本的套接字编程,以便客户端和服务器之间能进行数据交互。下面我们将深入探讨这个模型及其关键知识点。 首先,客户端-服务器模型的基本...

Global site tag (gtag.js) - Google Analytics