最近再学习java的web编程,发现用java创建一个小的服务器和客户端是如此的简单,引用经典图书《Tomcat与Java Web开发技术详解(第二版)》(孙卫琴)

根据书中案例敲代码自己学习,放这里记录一下,以便复习:)

服务器端程序,接收客户端程序发出的HTTP请求,把它打印到控制台,然后解析HTTP请求,并向客户端发回相应的HTTP响应。

HTTPServer类中service()方法中,先读取HTTP请求数据,然后获得HTTP请求中的URL,随后创建一个读取本地文件的输入流,该文件的路径由URI决定

HTTPServer.java:

package server;
import java.io.*;
import java.net.*;

public class HTTPServer {
    public static void main(String args[]) {
        int port;
        ServerSocket serverSocket;
        try {
            port = Integer.parseInt(args[0]);
        }catch (Exception e) {
            System.out.println("port = 8080 (默认)");
            port = 8080;
        }
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("服务器正在监听端口:"+serverSocket.getLocalPort());
            while(true) {
                try {
                //等待客户端的TCP连接请求
                final Socket socket = serverSocket.accept();
                System.out.println("建立了与客户的一个新的TCP连接,该客户的地址为:"
                +socket.getInetAddress()+":"+socket.getPort());
                service(socket);
                } catch(Exception e) {e.printStackTrace();}
            } //#while
        } catch(Exception e) {e.printStackTrace();}
    }
    /*响应客户的HTTP请求*/
    public static void service(Socket socket) throws Exception {
        /*读取HTTP请求信息*/
        InputStream socketIn = socket.getInputStream();    //获得输入流
        Thread.sleep(500);    //睡眠500毫秒,等待HTTP请求
        int size = socketIn.available();
        byte[] buffer = new byte[size];
        socketIn.read(buffer);
        String request = new String(buffer);
        System.out.println("http请求数据: \n"+request);    //打印HTTP请求数据
        
        /*解析HTTP请求*/
        //获得HTTP请求的第一行
        String firstLineOfRequest=request.substring(0,request.indexOf("\r\n"));
        //解析HTTP请求的第一行
        String[] parts = firstLineOfRequest.split(" ");
        String uri = parts[1];    //获得HTTP请求中的uri
        
        /*决定HTTP响应正文的类型,此处做了简化处理*/
        String contentType;
        if(uri.indexOf("html")!= -1 || uri.indexOf("htm") != -1)
            contentType = "text/html";
        else if(uri.indexOf("jpg")!= -1 || uri.indexOf("jpeg")!= -1)
            contentType = "image/jpeg";
        else if(uri.indexOf("gif")!= -1)
            contentType = "image/gif";
        else
            contentType = "application/octet-stream";    //字节流类型
        
        /*创建HTTP响应结果*/
        //HTTP响应的第一行
        String responseFirstLine = "HTTP/1.1 200 OK\r\n";
        //HTTP响应头
        String responseHeader = "Content-Type:"+contentType+"\r\n\r\n";
        //获得读取响应正文数据的数据流
        InputStream in = HTTPServer.class.getResourceAsStream("root/"+uri);
        
        /*发送HTTP响应结果*/
        OutputStream socketOut = socket.getOutputStream();    //获取数据流
        //发送HTTP响应的第一行
        socketOut.write(responseFirstLine.getBytes());
        //发送HTTP响应头
        socketOut.write(responseHeader.getBytes());
        //发送HTTP响应的正文
        int len=0;
        buffer = new byte[128];
        while((len=in.read(buffer))!=-1)
            socketOut.write(buffer,0,len);
        
        Thread.sleep(1000);    //睡眠1秒,等待客户端接受HTTP响应结果
        socket.close();    //关闭TCP连接
    }
}

客户端程序,以GET方式向HTTP服务器发送HTTP请求,然后把接收到的HTTP响应结果打印到控制台,并没有进行解析

HTTPClient.java

package client;
import java.io.*;
import java.net.*;
import java.util.*;

public class HTTPClient {
    public static void main(String args[]) {
        //确定HTTP请求的uri
        String uri = "Welcome.html";
        if(args.length !=0)
            uri=args[0];
        
        doGet("localhost",8080,uri);    //按照GET请求方式访问HTTPServer
    }
    
    /**按照GET请求方式访问HTTPServer */
    private static void doGet(String host, int port, String uri) {
        // TODO Auto-generated method stub
        Socket socket = null;
        try{
            socket = new Socket(host,port);        //与HTTPServer建立TCP连接
        }catch (Exception e){e.printStackTrace();}
    
    try{
        /*创建HTTP请求*/
        StringBuffer sb = new StringBuffer("GET "+uri+" HTTP/1.1\r\n");        //HTTP请求的第一行
        //HTTP请求头
        sb.append("Accept: */*\r\n");
        sb.append("Accept-Language: zh-cn\r\n");
        sb.append("Accept-Encoding: gzip, deflate\r\n");
        sb.append("User-Agent: HTTPClient\r\n");
        sb.append("Host: localhost:8080\r\n");
        sb.append("Connection: Keep-Alive\r\n\r\n");
        
        /*发送HTTP请求*/
        OutputStream socketOut = socket.getOutputStream();        //获得输出流
        socketOut.write(sb.toString().getBytes());

Thread.sleep(2000);        //睡眠2秒,等待响应结果
        
        /*接受响应结果*/
        InputStream socketIn = socket.getInputStream();
        int size = socketIn.available();
        byte[] buffer = new byte[size];
        socketIn.read(buffer);
        System.out.println(new String(buffer));        //打印响应结果
        
    }catch(Exception e){
        e.printStackTrace();
        }finally{
            try{
                socket.close();
            }catch(Exception e){e.printStackTrace();}
        }
    }
}

客户端参数&服务端本地文件Hello1.html:

<html>
<head>
<title>
HelloWorld!
</title>
</head>
<body>
<h1>Hello</h1>    
<img src="xiongbenxiong.gif" align="middle"/>
</body>
</html>

运行结果:

浏览器显示:

用java套接字创建HTTP客户与服务器程序的更多相关文章

  1. 用Python套接字创建HTTP客户与服务器程序

    最近在学习python,网络编程中,python寥寥几句,就可以创建一个服务端和客户端程序: 服务端: import sockets = socket.socket()host = socket.ge ...

  2. [置顶] Java套接字Socket编程

    1)概念 网络编程基本模型就客户端到服务器的模型,也就是我们常见的C/S模型.简单的说就是两个进程间相互通信的过程.即通信双方一方作为服务器等待客户端提出请求并给以回应,另一方作为客户端向服务器提出请 ...

  3. Java套接字

    前言: 本文补充一下Java关于套接字方面的内容,因为其应用相对比较简单,所以下面介绍两个程序实例. ------------------------------------------------- ...

  4. java套接字(socket)实例

    客户端socket 流程: 1.连接远程主机 2.发送数据 3.接收数据 4.关闭流与socket连接 实例: import java.io.*; import java.net.Socket; im ...

  5. Java套接字Socket编程--TCP参数

    在Java的Socket中,主要包含了以下可设置的TCP参数. 属性 说明 默认值 SO_TIMEOUT 对ServerSocket来说表示等待连接的最长空等待时间; 对Socket来说表示读数据最长 ...

  6. Java套接字实现应用程序对数据库的访问

    最近在完成软件体系结构上机实验时,遇到一个有点点小难度的选做题,题目信息如下: 利用套接字技术实现应用程序中对数据库的访问.应用程序只是利用套接字连接向服务器发送一个查询的条件,而服务器负责对数据库的 ...

  7. 【Unix网络编程】 chapter5 TCP客户,服务器程序实例

    chapter5 5.1 概述 5.2 TCP回射服务器程序:main函数 int main(int argc, char **argv) { int listenfd,connfd; pid_t c ...

  8. Java套接字socket编程笔记

    相对于C和C++来说,Java中的socket编程是比较简单的,比较多的细节都已经被封装好了,每次创建socket连接只需要知道地址和端口即可. 在了解socket编程之前,我们先来了解一下读写数据的 ...

  9. java套接字实现接口访问

    是学校博客上的:http://blog.csdn.net/z69183787/article/details/17580325

随机推荐

  1. 重读C#委托、事件有感

    去年学习C#的时候按照进度把C#的委托和事件“认真”的学习了一下,自己知道委托和事件的重要性,所以也努力的学习,可说实也没怎么学懂.碰巧这段时间在做一个解析GPS数据的小项目,因为其中有需要条件自动判 ...

  2. PPPoE名词解释

    PPPoE拔号的发现阶段(Discovery): PPPoE的发现阶段一共分为4步. 分别是: PADI(PPPoE Active Discovery Initiation) PADO(PPPoE A ...

  3. Windows下MySQL 5.6安装及配置详细图解

    一.安装前的准备 1.下载安装程序包,可到MySQL官方网站http://www.mysql.com/下载,如图1-1: 图1-1 下载后的安装文件如图1-2所示: 图1-2 二.安装 1.双击下载的 ...

  4. centos 安装mysql

    wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-rele ...

  5. 超级强大的formValidator

    来源: http://www.cnblogs.com/wzmaodong http://www.neatstudio.com/show-73-1.shtml  (全) http://www.cnblo ...

  6. 【转】phpcms授课学习

    来自:http://blog.csdn.net/yanhui_wei/article/category/1220735 <?php 思路: 一.目前在企业中使用比较多的cms内容管理有如下几种: ...

  7. leetcode 33. Search in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...

  8. Android学习笔记(十八)——再谈升级数据库

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 之前我们为了保证数据库中的表是最新的,只是简单地在 onUpgrade()方法中删除掉了当前所有的表,然后强制 ...

  9. Pythhon 字典 key in dict 比 dict.has_key (key)效率高 为什么?

    has_key是去取key对应的值,时间复杂度在最优情况下为O(1); in 是直接去dict.__contains__这个保存这key的list中去获取,相当与是去数组中获取. 所以in 比has_ ...

  10. Linux之ls命令

    s 命令可以说是linux下最常用的命令之一. -a 列出目录下的所有文件,包括以 . 开头的隐含文件.-b 把文件名中不可输出的字符用反斜杠加字符编号(就象在C语言里一样)的形式列出.-c 输出文件 ...