简单的Client/Server程序
C/S 架构全称为客户端 / 服务器体系结构,它是一种网络体系结构,其中客户端是用户运行应用程序的 PC端或者工作站,客户端要依靠服务器来获取资源。 C/S 架构是通过提供查询响应而不是总文件传输来减少 了网络流量。它允许多用户通过 GUI 前端更新到共享数据库,在客户端和服务器之间通信一般采用远程 调用 RPC 或标准查询语言 SQL 语句。
C/S 架构的基本特征:
- 客户端进程包含特定于解决方案的逻辑,并提供用户与应用程序系统其余部分之间的接口。服务器进程充当管理共享资源(如数据库,打印机,调制解调器或高性能处理器)的软件引擎
- 前端任务和后端任务对计算资源有着根本不同的要求,例如处理器速度,内存,磁盘速度和容量以及输入/ 输出设备
- 客户端和服务器的硬件平台和操作系统通常不相同。客户端和服务器进程通过一组明确定义的标准应用程序接口API和RPC进行通信
- C/S架构的一个重要特征是可扩展性,它们可以水平或垂直缩放。水平扩展意味着添加或删除客户端,工作站只会对性能产生轻微影响。垂直扩展意味着迁移到更大更快的服务器计算机或多服务器中。
服务器端套路
创建 ServerSocket 对象,绑定监听端口。
通过 accept 方法监听客户端请求。
连接建立后,通过输入流读取客户端发送的请求信息。
通过输出流向客户端发送响应信息。
关闭响应的资源。
ServerSocket ss=new ServerSocket(8000);
//阻塞当前线程的执行,并等待客户端的链接请求,如果链接成功则返回一个Socket对象
Socket socket=ss.accept();
//通过链接对象Socket可以获取一个输入流和一个输出流
InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();
//具体的数据接收处理逻辑
BufferedReader br=new BufferedReader(new InputStreamReader(is));
//这里使用的是BIO,所以当客户端没有发送数据时,会阻塞等待
String str=br.readLine();
System.out.println("Server:"+str);
//服务器回传系统当前时间 PrintStream ps=new PrintStream(os);
Date now=new Date();
DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sdate=df.format(now);
ps.println(sdate);
ps.flush();
//发送完毕,关闭流和套接字,完善的写法为try-finally结构
ps.close();
br.close();
socket.close();
客户端套路
创建 Socket 对象,指明需要连接的服务器的地址和端口号。
连接建立后,通过输出流向服务器发送请求信息。
通过输入流获取服务器响应的信息。
关闭相应资源。
//也可以使用回绕地址127.0.0.1。注意这里的端口号必须和服务器的端口号一致,否则不能链接
//如果链接成功则返回Socket对象
Socket socket=new Socket("localhost",8000);
//通过链接对象Socket可以获取一个输入流和一个输出流
InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();
//具体的请求逻辑
PrintStream ps=new PrintStream(os);
ps.println("Hello Server!");//向服务器发送一个内容为Hello Server!的字符串
//客户端接收服务器传回的系统当前时
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String sdate=br.readLine();//阻塞等待
System.out.println("Client:"+sdate);
//关闭
br.close();
ps.close();
socket.close();
一般的编程实现方式
主线程一直处于阻塞等待状态,如果一旦链接建立成功则启动一个新线程对外提供服务,而主线程继续等待连接请求
依据:监听端口在连接创建期间被占用,连接一旦创建则继续处于空闲状态
public class MyServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(9999);
while (true) {
Socket socket = server.accept();
new MyWorker(socket).start();
}
}
}
class MyWorker extends Thread {
private Socket socket;
public MyWorker(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
PrintStream ps = null;
try {
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
br = new BufferedReader(new InputStreamReader(is));
ps = new PrintStream(os);
String ss = br.readLine();
System.out.println("Client:" + ss);
if ("hello".equals(ss)) {
Date now = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-ddE hh:mm:ss");
ss = df.format(now);
ps.println(ss);
}
} catch (Exception e) {
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if (ps != null)
ps.close();
if (socket != null)
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
c/s和b/s区别
- C/S (Client/Server,客户机/服务器)结构,胖客户端应用,是软件系统体系结构的一种。C/S模式简单地讲就是基于企业内部网络的应用系统,大部分的应用逻辑都集中在客户端中,而一般服务器端只提供数据的存储。与B/S(Browser/Server,浏览器/服务器)模式相比,C/S模式的应用系统最大的好处是不依赖企业外网环境,即无论企业是否能够上网,都不影响应用。
- B/S结构(Browser/Server结构)结构即浏览器和服务器结构,瘦客户端应用,主要逻辑集中在服务器端,客户端一般只包含的简单的显示逻辑。它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端Browser实现,但是主要事务逻辑在服务器端Server实现,形成所谓三层3-tier结构。
C/S聊天室的实现
服务器端应用包含多个线程,每个 Socket 对应一个线程,该线程负责读取 Socket 对应输入流的数据,并将读到的数据向每个 Socket 发送一次
每个客户端应该包含两个线程,一个负责读取用户键盘输入并将用户输入数据写入 Socket 对应的流中,一个负责读取 Socket 对应输入流的数据并打印显示