最近在面试,虽然学习了一些新的框架,但是可能问类似于客户端服务器模型,然后根据其设计,所以就根据面试内容梳理一下客户端服务器模型。

客户端基本思路:

1.创建Socket实例,设置端口和IP地址等

2.通过Socket实例,获取到流对象

3.通过流对象,向其中输入数据 ,并且在完成后实现关闭流。

(注意事情:1.需要进行异常处理 2.注意关闭流和Socket 3.低级流和高级流的关闭顺序)

//客户端程序
package ServerSocket; import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket; public class ClientDome { public static void main(String[] args) { Socket socket =null; OutputStream outputStream=null; BufferedOutputStream bufferedOutputStream=null;
try {
socket=new Socket("localhost", 6060); outputStream=socket.getOutputStream(); bufferedOutputStream =new BufferedOutputStream(outputStream); String str ="Client Dome ..... Are you ok"; bufferedOutputStream.write(str.getBytes()); bufferedOutputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
bufferedOutputStream.close(); outputStream.close();
socket.close();
} catch (IOException e) { e.printStackTrace();
}
}
} }

  服务器模型构建:

1.创建一个ServerSocket对象,进行端口监听。

2.while(true)重复监听

3.通过端口监听对象 获取Socket实例 并且获取到网络流

4.输出网络流数据 并且关闭流

(注意事情:端口监听一次 获取监听对象多次 低级流和高级流的关闭顺序)

//首先这是单线程版本
package ServerSocket; import java.io.BufferedInputStream; import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; public class ServerSocketDome { @SuppressWarnings("null")
public static void main(String[] args) { // 1.建立监听 ServerSocket serverSocket = null;
InputStream inputStream = null;
BufferedInputStream bufferedInputStream = null; @SuppressWarnings("unused")
Socket socket = null; try {
serverSocket =new ServerSocket(6060);
while(true){
socket = serverSocket.accept(); inputStream = socket.getInputStream(); bufferedInputStream = new BufferedInputStream(inputStream); byte[] bytes=new byte[10];
int len=0;
while((len=bufferedInputStream.read(bytes))!=-1){ System.out.print(new String(bytes, 0, len));
}
} } catch (IOException e) {
e.printStackTrace();
} finally { try {
if(bufferedInputStream!=null){
bufferedInputStream.close();
inputStream.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} }

  多线程版本怎么操作,这里即将引入多线程

服务器版本多线程主要是对于请求分线程操作 ,一次连接会单独分配线程

package ServerSocket;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; //为了应对面试需要 尝试根据自己思路写一个新的多线程版本试试
//其实多线程版本是根据单线程改进而来
//具体而言 多线程的服务器 是应对多条请求 不同线程进行处理
public class ServerSocketThreadDome { public static void main(String[] args) {
//当然 主线程的端口监听是不能修改的
ServerSocket serverSocket = null;
//标准web服务器的端口是8080
int port=6060; try {
serverSocket=new ServerSocket(port); Socket socket=null;
while(true){
socket=serverSocket.accept(); new Thread(new Server(socket)).start();
} } catch (IOException e) {
e.printStackTrace();
}finally{
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} } //这里的多线程说白了 就是为了应对多条请求而处理的结果
//也就是客户端对象
class Server implements Runnable{
private Socket socket; public Server(Socket socket) {
super();
this.socket = socket;
} @Override
public void run() {
InputStream inputStream=null;
BufferedInputStream bufferedInputStream =null; try {
inputStream = socket.getInputStream();
bufferedInputStream=new BufferedInputStream(inputStream); byte[] bytes=new byte[1024];
int len=0;
while((len=bufferedInputStream.read(bytes))!=-1){ System.out.print(new String(bytes, 0, len));
System.out.println("当前线程:"+Thread.currentThread().getName());
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(bufferedInputStream!=null){
bufferedInputStream.close();
inputStream.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} } }

  那么我们引入线程池的概念 有时候面试可能会问线程池

package ServerSocket;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; //首先大话一下线程池,线程池类似于中介结果,我需要的时候找中介借一些人过来
//不需要的时候中介自己回去 我不需要提供其他待遇等等
//就是传说中的国企或者大型企业的外包部门
public class ServerSocketPoolDome { public static void main(String[] args) {
ServerSocket serverSocket = null;
//标准web服务器的端口是8080
int port=6060; try {
serverSocket=new ServerSocket(port); Socket socket=null; ExecutorService executorService =Executors.newCachedThreadPool();
while(true){
socket=serverSocket.accept(); executorService.execute(new ServerPool(socket));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }
//这里的多线程说白了 就是为了应对多条请求而处理的结果
//也就是客户端对象
class ServerPool implements Runnable{
private Socket socket; public ServerPool(Socket socket){
super();
this.socket = socket;
} @Override
public void run() {
InputStream inputStream=null;
BufferedInputStream bufferedInputStream =null; try {
inputStream = socket.getInputStream();
bufferedInputStream=new BufferedInputStream(inputStream); byte[] bytes=new byte[1024];
int len=0;
while((len=bufferedInputStream.read(bytes))!=-1){ System.out.print(new String(bytes, 0, len));
System.out.println("当前线程:"+Thread.currentThread().getName());
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(bufferedInputStream!=null){
bufferedInputStream.close();
inputStream.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} } }

线程池的使用很爽,接下来看看线程池的源码

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
//线程池创建一个缓冲的线程池
//也就设置线程数目 和 活动时间 以及具体执行的方式

  

最新文章

  1. EventBus实现activity跟fragment交互数据
  2. js获取上传的文件并用ajax提交
  3. [BS-31]导航控制器的interactivePopGestureRecognizer属性
  4. linux内核调优详解
  5. 屏幕 Dynpro
  6. mysql innoDB 与 myISAM
  7. Tomcat9源码编译及导入Eclipse(转)
  8. to config RBS/RBLOB in sharepoint
  9. Word删除复制后产生空行
  10. Android Service 通过 BroadcastReceiver 更新Activity UI
  11. 【LeetCode】119. Pascal&#39;s Triangle II
  12. 【源码解析】Sharding-Jdbc中的算法
  13. UbuntuNFS服务器配置
  14. MySQL免安装版,遇到MSVCR120.dll文件丢失错误的解决方案
  15. [Installing Metasploit Framework on CentOS_RHEL 6]在CentOS_RHEL 6上安装Metasploit的框架【翻译】
  16. Edit Distance II
  17. 侯捷STL课程及源码剖析学习2: allocator
  18. Spring基础(1) : 自动装配
  19. free命令中buffers和caches的区别
  20. Android Studio错误提示:Gradle project sync failed. Basic functionality (eg. editing, debugging) will not work properly

热门文章

  1. nginx之location详解
  2. net core天马行空系列:原生DI+AOP实现spring boot注解式编程
  3. 以后可得记住了--Python笔试面试题小结
  4. python 05 字典
  5. 设置ABP默认使用中文
  6. POJ 1015 陪审团问题
  7. mysql中的截取函数及其实例
  8. ASP.NET Core on K8S深入学习(9)Secret &amp; Configmap
  9. 五月月赛 寻宝 exkmp + 主席树
  10. poj 2240 Arbitrage(Bellman_ford变形)