用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>
运行结果:
浏览器显示:
用java套接字创建HTTP客户与服务器程序的更多相关文章
- 用Python套接字创建HTTP客户与服务器程序
最近在学习python,网络编程中,python寥寥几句,就可以创建一个服务端和客户端程序: 服务端: import sockets = socket.socket()host = socket.ge ...
- [置顶] Java套接字Socket编程
1)概念 网络编程基本模型就客户端到服务器的模型,也就是我们常见的C/S模型.简单的说就是两个进程间相互通信的过程.即通信双方一方作为服务器等待客户端提出请求并给以回应,另一方作为客户端向服务器提出请 ...
- Java套接字
前言: 本文补充一下Java关于套接字方面的内容,因为其应用相对比较简单,所以下面介绍两个程序实例. ------------------------------------------------- ...
- java套接字(socket)实例
客户端socket 流程: 1.连接远程主机 2.发送数据 3.接收数据 4.关闭流与socket连接 实例: import java.io.*; import java.net.Socket; im ...
- Java套接字Socket编程--TCP参数
在Java的Socket中,主要包含了以下可设置的TCP参数. 属性 说明 默认值 SO_TIMEOUT 对ServerSocket来说表示等待连接的最长空等待时间; 对Socket来说表示读数据最长 ...
- Java套接字实现应用程序对数据库的访问
最近在完成软件体系结构上机实验时,遇到一个有点点小难度的选做题,题目信息如下: 利用套接字技术实现应用程序中对数据库的访问.应用程序只是利用套接字连接向服务器发送一个查询的条件,而服务器负责对数据库的 ...
- 【Unix网络编程】 chapter5 TCP客户,服务器程序实例
chapter5 5.1 概述 5.2 TCP回射服务器程序:main函数 int main(int argc, char **argv) { int listenfd,connfd; pid_t c ...
- Java套接字socket编程笔记
相对于C和C++来说,Java中的socket编程是比较简单的,比较多的细节都已经被封装好了,每次创建socket连接只需要知道地址和端口即可. 在了解socket编程之前,我们先来了解一下读写数据的 ...
- java套接字实现接口访问
是学校博客上的:http://blog.csdn.net/z69183787/article/details/17580325
随机推荐
- VBA 表操作1
VBA 新建表.批量建表 例1 创建一个工作簿 注意 .name 与 .range ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- QT点击"X"按钮,调用closeEvent()函数来实现调用特定事件(附:粗略介绍QT的信号与槽的使用方法)
背景: QT在用户关闭窗口(直接点击"X"键)时,程序一般都需要做一些善后的事情,就我现在的程序来说,既关闭USB.如何实现? 正文: 首先,在对应窗体的".h" ...
- Javascript高级程序设计——函数
函数Function 通过函数封装多条语句,在任何地方执行.javascript函数不会重载,相同名字函数,名字属于后定义的函数通过function关键词声明. function functionNa ...
- JS数组的基本用法
JS数组的用法包括创建.取值赋值.添加以及根据下标(包括数值或字符)来移除元素等等,在本文中将为大家详细介绍,感兴趣的朋友可以参考下. 1.创建数组: //1.1直接创建一个数组对象 var arra ...
- 【转】phpcms-v9中关于模型的理解
PHPCMS v9 模型概念 一.什么是模型? 模型是系统知识的抽象表示.我们不能仅仅通过语言来描述一个系统,也不能仅仅通过记忆来记录关于系统的知识.知识是通过某种媒介来表达的,这种媒介所表达的内容就 ...
- Effective Java 学习笔记之创建和销毁对象
一.考虑用静态工厂方法代替构造器 1.此处的静态工厂方法是指返回指为类的对象的静态方法,而不是设计模式中的静态工厂方法. 2.静态工厂方法的优势有: a.使用不同的方法名称可显著地表明两个静态工厂方法 ...
- HDU 4939 Stupid Tower Defense(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4939 解题报告:一条长度为n的线路,路上的每个单元格可以部署三种塔来给走在这条路上的敌人造成伤害,第一 ...
- 关于JavaScript的浅拷贝和深拷贝
在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...
- Oracle sysdate 时间加减
加法 select sysdate,add_months(sysdate,12) from dual; --加1年 select sysdate,add_months(sysdate,1 ...
- git 教程(6)--管理修改
现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问,什么是修改?比如你新增了一行,这就是一个修改 ...