用java套接字创建HTTP客户与服务器程序

最近再学习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>

运行结果:

浏览器显示:

时间: 2024-07-30 20:25:56

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

Java套接字Socket

这篇博客是本人学习<Java网络程序设计>书中第4章套接字的学习总结.初学者网友学习这篇Java套接字文章,如果难于理解文章前面理论部分,可以先运行后面的程序,边看运行后面的程序边理解前面的原理,这对初学者是最好的方法.所有源代码都在文章后面我的github链接代码中. --惠州学院 13网络工程 吴成兵 20160607 目录 1 目录 1 一 流套接字概述 二 服务器套接字ServerSocket 21 ServerSocket的工程过程 22 ServerSocket构造方法 23 Se

Java套接字编程实现群聊与私聊[原理版]

简介 运用Java套接字我们几乎可以完成一个网络聊天软件的小产品,本文不涉及UI部分,仅对原理部分用代码演示一下.一个可以多人聊天的小功能,在Linux系统上用telnet亲测可用. 服务器代码 package demo0811.demo3; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.

Java套接字

前言: 本文补充一下Java关于套接字方面的内容,因为其应用相对比较简单,所以下面介绍两个程序实例. --------------------------------------------------------------------------------------- 1.Socket对接过程 (注:这是之前在网上见过一张图片,大致过程还是比较清晰的) 分析: Socket对接之后的数据传送类似于文件的读写: 流套接字采用TCP传输数据流,一旦数据发送失败将重传,所以具有安全无损的特点.

java套接字(socket)实例

客户端socket 流程: 1.连接远程主机 2.发送数据 3.接收数据 4.关闭流与socket连接 实例: import java.io.*; import java.net.Socket; import java.util.Date; /** * Created by CLY on 2017/7/11. */ public class ClientSocket { public static void main(String[] arg){ int port = 233;//与之连接的服务

JAVA套接字(Socket)101七天系列—第四天【一个简单示例】

一个简单示例  1. 背景 我们将在本部分讨论的示例将阐明在 Java 代码中如何使用 Socket 和 ServerSocket.客户机用Socket 连接到服务器.服务器用 ServerSocket 在端口 3000 侦听.客户机请求服务器 C: 驱动器上的文件内容. 为清楚起见,我们把示例分解成客户机端和服务器端.最后我们将把它们组合起来以使您能看到整体模样. 我们在使用 JDK 1.2 的 IBM VisualAge for Java 3.5 上开发这些代码.要自己创建这个示例,您应有完

基于JAVA套接字的简单网络聊天程序

网络中进程之间如何通信 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用(Solaris门和Sun RPC) 但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的.其实TCP/IP协议族已经帮我们解决了这个问题,网

《JAVA套接字》

套接字(socket)为两台计算机之间的通信提供了一种机制,在 James Gosling 注意到 Java 语言之前,套接字就早已赫赫有名.为了能够方便开发网络应用程序,Unix系统推出了一种应用程序访问通信协议的操作系统调用——Socket套接字,使得程序员很方便的访问TCP/IP协议,从而开发各种网络应用程序.后来Windows也引入Socket,Java语言也引入了套接字的编程模型. 多数程序员,不管他们是否使用 Java 语言进行编码,都不想很多知道关于不同计算机上的应用程序彼此间如何

Java套接字编程

实现了基于TCP的Java Socket编程实例代码:简单实现了服务器和客户端的套接字编程,并传递简单的字符串.(在服务器声明套接字时需要绑定服务器的端口,端口为临界资源只能一个套接字使用.服务器编程时调用accept()方法,服务器进入等待连接状态.) Java中TCP/IP服务端连接建立的源码实现(socket->bind->listen->accept): (1)在进行套接字编程的时候,首先我们要建立一个服务端,并在服务端建立套接字,为套接字绑定接口,然后监听客户端可能发来的连接建

Java套接字编程向服务器进行读写数据

简介 套接字最初叫伯克利套接字,因为是由伯克利大学最初发明的.在Java中,可以很方便地调用Socket进行网络通信.下面,就试着用套接字向远程服务器进行读写数据. 代码演示 package demo0811.demo1; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.Input