网络编程
1 什么是网络编程
网络编程的本质是两个设备之间的数据交换,当然,在计算机网
络中,设备主要指计算机。数据传递本身没有多大的难度,不
就是把一个设备中的数据发送给两外一个设备,然后接受另外
一个设备反馈的数据。
现在的网络编程基本上都是基于请求/响应方式的,也就是一个
设备发送请求数据给另外一个,然后接收另一个设备的反馈。
在网络编程中,发起连接程序,也就是发送第一次请求的程序,
被称作客户端(Client),等待其他程序连接的程序被称作服务器
(Server)。客户端程序可以在需要的时候启动,而服务器为了
能够时刻响应连接,则需要一直启动。例如以打电话为例,首
先拨号的人类似于客户端,接听电话的人必须保持电话畅通
类似于服务器。
总结: 通过编码的方式让不同计算机之间通过网络相互
通信(传递数据)
2 网络编程要解决的核心的问题
1. 寻址: 使用ip+端口
2. 协议: 数据的传输规则|方式
3 常见的协议有哪些
1). UDP 协议
面向非连接的协议,传递数据时不关心连接状态直接发送,他的
传输效率高,传递的数据不安全
2). TCP/IP 协议
面向连接的协议,传递数据时关系连接的状态,连接成功才会发
送数据,他的传输效率相对于UDP协议要低,会通过三次握手机
制保证数据的完整性
3). Http 协议
属于应用层协议,层面比较高,http协议底层还是通过tcp协议传输
4 网络中的OSI模型
OSI是Open System Interconnection的缩写,意为开放
式系统互联. OSI 七层模型通过七个层次化的结构模型使
不同的系统不同的网络之间实现可靠的通讯,因此其最主
要的功能就是帮助不同类型的主机实现数据传输
注意: 所处的层越低传输效率越高
5 常见的网络编程
浏览器 ---------------------> 服务器
chorme tomcat
c/s:访问某个服务器端的时候,需要特定的客户端
b/s:浏览器,是一个公共的客户端,通过浏览器可以给不同
的服务器发送数据
客户端:
1 c/s模式中对应的客户端
2 b/s中的浏览器,通用的客户端
3 通过代码实现: http-client(模拟浏览器)
4 自己书写一个客户端
服务器:
自己编写
6 java中网络编程的实现方式
java中实现网络编程,也叫(Socket)编程,通过java实现
网络编程主要有以下几种方式
1 java BIO:基于java阻塞io实现网络编程
(Block IO 同步阻塞IO)
2 java NIO:基于java的同步非阻塞IO实现网络编程
(New IO 同步非阻塞IO)
7 java中网络编程的开发思路
使用java语言开发网络编程,主要用到其核心类:Socket,翻译
为:套接字,socket类中封装了系列网络编程的api
1 开发服务端
ServerSocket:专门用来书写服务器端
1 服务器端一直活着
2 服务器端的accept()能够重复调用
2 开发客户端
Socket:专门用来书写客户端
8 网络编程的实现
8.1 网络编程开发服务器端
package com.yxj.servers;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 创建serverScoket对象 服务端对象
*/
public class TestServerSocket {
public static void main(String[] args) throws IOException {
//创建一个服务器
ServerSocket serverSocket = new ServerSocket(8989);
System.out.println("服务器已经启动........");
while(true) {
//让服务器接受|接收客户端
Socket socket = serverSocket.accept();
//处理请求数据
InputStream inputStream = socket.getInputStream();
StringBuilder builder = new StringBuilder();
int len = 0;
byte[] b = new byte[1024];
while (true) {
len = inputStream.read(b);
if (len == -1) break;
builder.append(new String(b, 0, len));
}
System.out.println(builder.toString());
socket.shutdownInput();//获取请求数据 结束
//处理业务
//服务端响应客户端数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("讲".getBytes());
socket.shutdownOutput();
}
}
}
8.2 网络编程开发客户端
package com.yxj.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
//创建客户端对象
public class TestSocket {
public static void main(String[] args) throws IOException {
//创建socket对象
Socket socket = new Socket("192.168.0.3", 8989);
//向服务器发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello Server".getBytes());
//代表客户端发送的数据完成
socket.shutdownOutput();
//获取服务器端响应数据
InputStream inputStream = socket.getInputStream();
int len = 0;
byte[] b = new byte[1024];
StringBuilder builder = new StringBuilder();
while(true){
len = inputStream.read(b);
if(len==-1) break;
builder.append(new String(b,0,len));
}
System.out.println(builder.toString());
socket.shutdownInput();//确定读取响应数据结束
}
}
9 网络编程服务端之支持多客户端访问
TestSocket001
package com.yxj.client;
import java.io.*;
import java.net.Socket;
//创建一个客户端对象
public class TestSocket001 {
public static void main(String[] args) throws IOException {
//创建客户端对象
Socket socket = new Socket("192.168.0.3",8989);
//发送数据
OutputStream outputStream = socket.getOutputStream();
//封装过滤流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("abc");
dataOutputStream.flush();
socket.shutdownOutput();//请求数据发送完成
//处理响应结果
InputStream inputStream = socket.getInputStream();
//封装过滤流
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
socket.shutdownInput();//明确client处理响应完毕
}
}
TestSocket002
package com.yxj.client;
import java.io.*;
import java.net.Socket;
//创建一个客户端对象
public class TestSocket002 {
public static void main(String[] args) throws IOException {
for (int i = 0; i <100 ; i++) {
//创建客户端对象
Socket socket = new Socket("192.168.0.3",8989);
//发送数据
OutputStream outputStream = socket.getOutputStream();
//封装过滤流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("aaa");
dataOutputStream.flush();
socket.shutdownOutput();//请求数据发送完成
//处理响应结果
InputStream inputStream = socket.getInputStream();
//封装过滤流
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
socket.shutdownInput();//明确client处理响应完毕
}
}
}
TestSocket003
package com.yxj.client;
import java.io.*;
import java.net.Socket;
//创建一个客户端对象
public class TestSocket003 {
public static void main(String[] args) throws IOException {
//创建客户端对象
Socket socket = new Socket("192.168.0.3",8989);
//发送数据
OutputStream outputStream = socket.getOutputStream();
//封装过滤流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("ccc");
dataOutputStream.flush();
socket.shutdownOutput();//请求数据发送完成
//处理响应结果
InputStream inputStream = socket.getInputStream();
//封装过滤流
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
socket.shutdownInput();//明确client处理响应完毕
}
}
package com.yxj.servers;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//创建服务器端
public class TestServerSocket001 {
//操作 进程 开启多线程 进程数量有限的 系统上线 cpu 1 100000000 1
public static void main(String[] args) throws IOException, InterruptedException {
//创建serverSocket对象
ServerSocket serverSocket = new ServerSocket(8989);
System.out.println("服务器已经启动......");
while (true){
//接收客户端请求 每一个请求创建一个线程
Socket socket = serverSocket.accept();
//处理请求数据
InputStream inputStream = socket.getInputStream();
//封装过滤流
DataInputStream dataInputStream = new DataInputStream(inputStream);
String readUTF = dataInputStream.readUTF();
System.out.println(readUTF +" 线程名称:"+Thread.currentThread().getName());
socket.shutdownInput();//明确处理请求数据完毕
//处理业务
if(readUTF.equals("abc")){
Thread.sleep(10000);
}
//响应客户端对象
OutputStream outputStream = socket.getOutputStream();
//封装过滤流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("我是server,我已经将你发送的请求处理完毕,没事别来找我.....");
socket.shutdownOutput();//明确服务器响应完毕
}
}
}
10 服务端的多线程操作
10.1 开启多线程的方式
package com.yxj.threads;
public class TestThread {
public static void main(String[] args) {
//创建多线程 方式一: 实现runnable 方式二: 继承Thread类 方式三: 线程池
//方式一: 实现runnable接口 run方法
/*MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();*/
/*new Thread(new Runnable() {
public void run() {
System.out.println("线程名称: "+Thread.currentThread().getName());
}
}).start();*/
//方式二: extends Thread类
MyThread myThread = new MyThread();
myThread.start();
}
}
TestServerSocket001
package com.yxj.servers;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//创建服务器端
public class TestServerSocket001 {
//操作 进程 开启多线程 进程数量有限的 系统上线 cpu 1 100000000 1
public static void main(String[] args) throws IOException, InterruptedException {
//创建serverSocket对象
ServerSocket serverSocket = new ServerSocket(8989);
System.out.println("服务器已经启动......");
while (true){
//接收客户端请求 每一个请求创建一个线程
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
public void run() {
try {
//处理请求数据
InputStream inputStream = socket.getInputStream();
//封装过滤流
DataInputStream dataInputStream = new DataInputStream(inputStream);
String readUTF = dataInputStream.readUTF();
System.out.println(readUTF +" 线程名称:"+Thread.currentThread().getName());
socket.shutdownInput();//明确处理请求数据完毕
//处理业务
if(readUTF.equals("abc")){
Thread.sleep(10000);
}
//响应客户端对象
OutputStream outputStream = socket.getOutputStream();
//封装过滤流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("我是server,我已经将你发送的请求处理完毕,没事别来找我.....");
socket.shutdownOutput();//明确服务器响应完毕
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
11 线程池(Executors)的服务端
TestThreadPool
package com.yxj.threadpools;
import java.util.concurrent.*;
public class TestThreadPool {
public static void main(String[] args) {
//创建线程池对象
//参数1: 线程池中核心线程数量
//参数2: 线程池中最大线程数
//参数3: 线程池中线程的空闲时间
//参数4: 决定线程中线程的空闲时间的单位 TimeUnit
//参数5: 线程等待队列
//参数6: 创建线程工厂
//参数7: 用于被拒绝任务的处理程序
// 策略一: 直接拒绝 new ThreadPoolExecutor.AbortPolicy() RejectedExecutionHandler 线程拒绝处理器
// 策略二: 在调用execute方法的程序中执行该任务 new ThreadPoolExecutor.CallerRunsPolicy() 如果程序已经结束则丢弃任务
// 策略三: new ThreadPoolExecutor.DiscardOldestPolicy() 丢弃等待队列中的请求,然后重试 execute ,除非执行程序被关闭,在这种情况下,任务被丢弃。
// 策略四: new ThreadPoolExecutor.DiscardPolicy() 丢弃最后一次无法执行的任务 静默丢弃
ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(1);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
1, //核心线程池数量 银行窗口 3
2, //线程池最大线程数量 临时窗口 5-3
10, //空闲10
TimeUnit.SECONDS, //单位 秒
workQueue, //线程等待队列 银行中小板凳 2
threadFactory, //创建新线程工厂
new ThreadPoolExecutor.DiscardPolicy()); //拒绝处理器
//调用线程池对象中execute方法执行线程任务
/* for (int i = 1; i <=8 ; i++) {
threadPoolExecutor.execute(new MyRunnable());
}*/
threadPoolExecutor.execute(new Runnable() {
public void run() {
System.out.println("任务1 "+Thread.currentThread().getName());
}
});
threadPoolExecutor.execute(new Runnable() {
public void run() {
System.out.println("任务2 "+Thread.currentThread().getName());
}
});
threadPoolExecutor.execute(new Runnable() {
public void run() {
System.out.println("任务3 "+Thread.currentThread().getName());
}
});
threadPoolExecutor.execute(new Runnable() {
public void run() {
System.out.println("任务4 "+Thread.currentThread().getName());
}
});
}
}
class MyRunnable implements Runnable{
public void run() {
System.out.println("任务.......线程名称:"+Thread.currentThread().getName());
/*try {
//Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
}
TestThreadPool001
package com.yxj.threadpools;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThreadPool001 {
public static void main(String[] args) {
//无界线程池,可以进行自动线程回收 线程数目没有限制
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//固定线程池 线程池中线程数固定
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
//单一线程池 所有任务均在一个线程中执行
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
//提交线程任务
Future<?> submit = cachedThreadPool.submit(new Runnable() {
public void run() {
System.out.println("===============");
}
});
System.out.println(submit.isDone());
}
}
TestServerSocket002
package com.yxj.servers;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//创建服务器端
public class TestServerSocket002 {
//操作 进程 开启多线程 进程数量有限的 系统上线 cpu 1 100000000 1
public static void main(String[] args) throws IOException, InterruptedException {
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
//创建serverSocket对象
ServerSocket serverSocket = new ServerSocket(8989);
System.out.println("服务器已经启动......");
while (true){
//接收客户端请求 每一个请求创建一个线程
final Socket socket = serverSocket.accept();
executorService.submit(new Runnable() {
public void run() {
try {
//处理请求数据
InputStream inputStream = socket.getInputStream();
//封装过滤流
DataInputStream dataInputStream = new DataInputStream(inputStream);
String readUTF = dataInputStream.readUTF();
System.out.println(readUTF +" 线程名称:"+Thread.currentThread().getName());
socket.shutdownInput();//明确处理请求数据完毕
//处理业务
if(readUTF.equals("abc")){
Thread.sleep(10000);
}
//响应客户端对象
OutputStream outputStream = socket.getOutputStream();
//封装过滤流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("我是server,我已经将你发送的请求处理完毕,没事别来找我.....");
socket.shutdownOutput();//明确服务器响应完毕
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
12 图片总结
想要获取该该课程markdown笔记(脑图+笔记)。可以扫描以下
微信公众号二维码。或者搜索微信公众号-Java大世界。回复
网络编程,即可获取笔记获取方式。