客户端请求服务器端通信, Web 编程发展基础|乐字节
乐字节的小伙伴们,好久不见,甚是想念啊!
前面我发布的文章算是把Java初级基础阶段讲完了,接下来小乐将会给大家接着讲Java中级阶段——Javaweb。
首先,我们要看看Javaweb阶段主要重点掌握的知识:
- 了解C/S和B/S两种结构模式
- 理解Web应用程序的工作原理
- 实现第一个Servlet程序
- 理解程序的内部工作流程
- 掌握web.xml的基本配置
这篇文章我们先学习web发展基础。
1、 简单通信
回顾 Socket 编程给我们最大的感受,是可以在多台电脑之间进行数据的传输,这就是网络编程的开端和基础,通过客户端请求服务器端通信,直观了解 Web 编程。
Server
/**
* 服务器端,接收客户端请求并给出简单的响应
* @author Administrator
*/
public class Server {
public static void main(String[] args) throws IOException {
//1、创建服务器,指定端口ServerSocket(int port)
ServerSocket socket=new ServerSocket(8888);
//2、接收客户端连接
Socket client=socket.accept();
System.out.println("******************");
//获取数据的输入流
InputStream is=client.getInputStream();
//使用字符缓存流
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String msg="";
while((msg=br.readLine())!=null){
System.out.println(msg);
}
br.close();
}
}
乐字节原创
Client
/**
* 客户端:向服务器发送请求,并发送简单的消息
* @author Administrator
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//创建客户端 必须指定服务器+端口
Socket client=new Socket("localhost",8888);
//发送消息 请求资源
//获取发送流
OutputStream os=client.getOutputStream();
BufferedWriter br=new BufferedWriter(new OutputStreamWriter(os));
//写出消息,发送内容
String msg="hello I need some source";
br.write(msg);
br.close();
}
}
从上面的例子总结通信条件如下:
1)、需要有服务器端(server) :等待被请求,需要暴露ip 和 port
2)、需要有客户端(client):主动发起请求 ,知晓服务端的ip 和 port
3)、通信规则(协议):TCP/IP协议
ip用于定位计算机;端口号(定位程序),用于标识进程的逻辑地址,不同进程的标志;有效端口:0~65535,其中0~1024由系统使用或者保留端口,开发中建议使用1024以上的端口。
2. 不同请求
Client
package com.shsxt.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
/**
*
* @author Lj
*
* 客户端
*/
public class Client {
public static void main(String[] args) throws IOException {
// 通过系统默认类型的 SocketImpl 创建未连接套接字
Socket socket = new Socket();
//此类实现 IP 套接字地址(IP 地址 + 端口号)。它还可以是一个对(主机名 + 端口号),在此情况下,将尝试解析主机名
SocketAddress address = new InetSocketAddress("localhost",8898);
// 将此套接字连接到服务器,并指定一个超时值。 或者不指定超时时间
socket.connect(address, 1000);
OutputStream os = socket.getOutputStream();
os.write("time".getBytes());
os.flush();
socket.close();
}
}
Server
package com.shsxt.socket; import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
*
* @author Lj
* 服务端
* public class ServerSocketextends Object:此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
*/
public class Server {
public static void main(String[] args) throws IOException {
//创建绑定到特定端口的服务器套接字。
ServerSocket server = new ServerSocket(8898); // Socket accept() 侦听并接受到此套接字的连接。
Socket client = server.accept();
System.out.println("接收到连接"); InputStream is = client.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
byte[] req = new byte[1024];
// 接收客户端请求
int len = bis.read(req);
String reqStr = new String(req,0,len);
System.out.println(reqStr);
if(reqStr.equals("money")){
System.out.println("here's the money");
}else if(reqStr.equals("time")){
System.out.println("you have so much time");
}
client.close();
server.close();
}
}
3. 复杂请求
Client
package com.shsxt.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
/**
* @author Lj
* 客户端
*/
public class Client {
public static void main(String[] args) throws IOException {
// 通过系统默认类型的 SocketImpl 创建未连接套接字
Socket socket = new Socket();
//此类实现 IP 套接字地址(IP 地址 + 端口号)。它还可以是一个对(主机名 + 端口号),在此情况下,将尝试解析主机名
SocketAddress address = new InetSocketAddress("localhost",8898);
// 将此套接字连接到服务器,并指定一个超时值。 或者不指定超时时间
socket.connect(address, 1000); OutputStream os = socket.getOutputStream();
os.write("money".getBytes());
os.flush();
// 接收响应, 显示结果
InputStream is = socket.getInputStream();
byte[] result = new byte[1024];
int len = is.read(result);
String resultStr = new String(result,0,len);
System.out.println(resultStr);
socket.close();
}
}
Server
package com.shsxt.socket;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
*
* @author Lj 服务端 public class ServerSocketextends
* Object:此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
*/
public class Server {
public static void main(String[] args) throws IOException {
// 创建绑定到特定端口的服务器套接字。
ServerSocket server = new ServerSocket(8898); // Socket accept() 侦听并接受到此套接字的连接。
Socket client = server.accept();
System.out.println("接收到连接");
InputStream is = client.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
byte[] req = new byte[1024];
// 接收客户端请求
int len = bis.read(req);
String reqStr = new String(req, 0, len);
System.out.println(reqStr);
// 将接收到的请求封装成对象, 传送给请求的类
MyRequest request = new MyRequest();
MyResponse response = new MyResponse(); OutputStream os = client.getOutputStream();
if (reqStr.equals("money")) {
// 根据请求的信息, 构造处理的类
MyServlet s1 = new ServletMoney();
s1.service(request, response);
// 通过client的响应, 将结果响应回客户端
os.write("here's the money".getBytes());
os.flush();
} else if (reqStr.equals("time")) {
// 根据请求的信息, 构造处理的类
MyServlet s2 = new ServletTime();
s2.service(request, response);
// 通过client的响应, 将结果响应回客户端
os.write("you have somuch time".getBytes());
os.flush();
}
client.close();
server.close();
}
}
/*
* 我是一个有要求的人, 你请求的这个资源必须是满足我要求格式的类 作用:防止混乱,方便调用
* 这是我的标准
*/
interface MyServlet {
void service(MyRequest req, MyResponse resp);
}
class ServletMoney implements MyServlet {
/*
* @see com.shsxt.socket.MyServlet#service(com.shsxt.socket.MyRequest)
*/
@Override
public void service(MyRequest req, MyResponse resp) {
// 做出力所能及的处理
}
}
class ServletTime implements MyServlet {
/*
* @see com.shsxt.socket.MyServlet#service(com.shsxt.socket.MyRequest)
*/
@Override
public void service(MyRequest req, MyResponse resp) {
// 做出力所能及的处理
}
}
/*
* 请求信息都按规律封装在该对象
*/
class MyRequest {
}
class MyResponse {
}
随着客户需求越来越复杂,需要的功能越来越多,我们的服务器端需要处理的请求越来越多,需要区分不同的请求,还需要按照不同请求进行请求数据的提取以及资源的分配和运算还有逻辑的处理,最后还需要响应给客户端,这就使得服务器端代码越来越复杂,实现越来越困难。
根据以往的经验,双方进行通信只需要遵循一定的规则就可以很明确地知道各部分数据的含义,于是出现了网络更上层的应用协议(后面讲的 HTTP 协议),规定服务器端和客户端通信的规则。
客户端请求服务器端和服务器端响应客户端,都按照固定的规则,那么接收请求和相应数据这部分操作就可以固定下来,交给特定的一段代码来执行,从而减少服务器端的代码量,于是出现了接下来说的服务器。
4. 服务器的出现
当客户端请求的资源越来越丰富,需求越来越复杂,程序的核心就应该放在解决业务和 计算响应数据上,于是出现了服务器统一接收客户端处理并进行分发到不同的资源,由各个资源进行处理,最后结果交由服务器响应。
从上面的描述可以发现,现在所说的服务器只是负责接收请求,对请求进行分发,以及最后将获取的数据进行相应的固定框架,至于数据怎么计算得出还得根据具体的业务需求编 写(填充)代码。在没有业务需求的情况下就能将服务器准备出来,现在市面上的服务器有 很多,比较常用的有:Tomcat、JBOOS、IBM 的 WebSphere、BEA 的 WebLogic 以及 Apache 等。
好了,web发展基础就讲到这里了,下一文章将会给大家Javaweb的介绍和C/S、B/S体系结构,敬请关注乐字节哦~~~~
客户端请求服务器端通信, Web 编程发展基础|乐字节的更多相关文章
- C#Socket_TCP(客户端,服务器端通信)
客户端与服务器通信,通过IP(识别主机)+端口号(识别应用程序). IP地址查询方式:Windows+R键,输入cmd,输入ipconfig. 端口号:可自行设定,但通常为4位. 服务器端: usin ...
- javascript客户端与服务器端通信
高性能的网络通信包括以下方面:选择正确的数据格式和与之匹配的传输技术. 一.数据格式 用于传输的数据格式有: 1)html,仅适用于特定场合,传输数据量大,不过它可以节省客户端的CPU周期, 2)XM ...
- JavaScript中利用Ajax 实现客户端与服务器端通信(九)
一:Ajax (Asynchronous JavaScript and XML)不是一个新的技术,事实上,它是一些旧有的成熟的技术以一种全新的更加强大的方式整合在一起 Ajax的关键技术: 1.使用X ...
- android-------- socket 实现客户端与服务器端通信
前面介绍了Socket的简介和原理,今天简单的来实现一下客服端与服务器通信的功能 客服端 建立连接 try { socket = new Socket("192.168.1.100" ...
- io流+网络+线程池 实现简单的多客户端与服务器端通信
1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.io.OutputStream; 4 import ...
- Android客户端与服务器端通过DES加密认证
转载地址:http://blog.csdn.net/spring21st/article/details/6730283 由于Android应用没有像web开发中的session机制,所以采用PHPS ...
- 浅析Java web程序之客户端和服务器端交互原理(转)
转载自http://www.cnblogs.com/lys_013/archive/2012/05/05/2484561.html 1. 协议 a. TCP/IP整体构架概述 TCP/IP协议并不完全 ...
- 浅析Java web程序之客户端和服务器端交互原理
原文链接: https://www.iteye.com/topic/470019 1. 协议 a. TCP/IP整体构架概述 TCP/IP协议并不完全符合OSI的七层参考模型.传统的开放式系统互连参考 ...
- JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)
本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...
随机推荐
- 代码中的mysql语法问题
今天在代码中写了mysql的删除语句 String lpinsuredSQL=" delete from lpinsured a where a.insuredid='?InsuredID? ...
- maven 使用dependencyManagement统一管理依赖版本
今日思语:人生方方长长,努力把她磨成方圆,所以 加油咯~ 使用maven可以很方便的进行项目依赖的管理,即可以管理我们显示引入具体版本的依赖,也可以管理某些第三方引入的一些依赖的版本,从而能更好的实现 ...
- yii2 oracle 原生sql分页
$sql_list = "SELECT ID, FID, INSID, FLIGHTNO, DEPNAME, ARRNAME, to_char(DEPDATE,'yyyy-MM-dd HH2 ...
- LeetCode 708. Insert into a Cyclic Sorted List
原题链接在这里:https://leetcode.com/problems/insert-into-a-cyclic-sorted-list/ 题目: Given a node from a cycl ...
- 集成omnibus-ctl+ chef 制作一个可配置的软件包
前边有写过使用omnibus-ctl 制作软件包的,但是当时没有集成chef,只有一个空壳子,实际上omnibus-ctl 已经内置 了对于chef 的操作(但是我们还需要在添加一个依赖),以下简单说 ...
- PDE工具箱的简单使用
转载自Here matlab的PDE工具箱的简单使用 问题选择 边界条件选择 菜单按钮和简单使用 命令行输入pdetool,打开GUI编辑界面如下: 注意到工具栏上,就是我们要用到的,从左到右依次使用 ...
- GoCN每日新闻(2019-10-19)
GoCN每日新闻(2019-10-19) Go 1.13中的错误处理 https://tonybai.com/2019/10/18/errors-handling-in-go-1-13 golang核 ...
- SpringDataRedis的简单案例使用
一.SpringDataRedis环境搭建 第一步.导入坐标 <!-- 缓存 --> <dependency> <groupId>redis.clients< ...
- 深入理解数据库索引采用B树和B+树的原因
前面几篇关于数据库底层磁盘文件读取,数据库索引实现细节进行了深入的研究,但是没有串联起来的讲解为什么数据库索引会采用B树和B+树而不是其他的数据结构,例如平衡二叉树.链表等,因此,本文打算从数据库文件 ...
- K8S从入门到放弃
K8S介绍相关 kubernetes(K8S)集群及Dashboard安装配置 kubernetes(K8S)创建自签TLS证书 K8S Kubernetes 架构 K8S组件 K8S API对象 K ...