网页编程 : 上层的应用
网络编程 : 底层,关注数据如何传输,如何存储
节点 : 网络电子设备
节点与节点之间组成网络
IP : 表示节点
端口 : 区分不同的软件
URL : 互联网中资源的指针,统一资源定位符
协议 : 合同,标准,规范
传输层协议 :
UDP : 相当于写信 只管写只管发 效率高 不安全 大小存在限制
TCP : 相当于打电话 面向连接 安全性高 效率低 大小没有限制 ****
一、基础知识
1.IP
? 定义网络中的节点 (网络电子设备,手机,电脑,路由器…)
分为 : IPV4(4个字节,32位) IPV6 (128位)
特殊IP:
192.168.0.0~192.168.255.255 非注册IP,供组织内部使用
127.0.0.1 本地IP
localhost : 本地域名
域名与IP之间的关系: DNS解析器
java.net包
InetAddress 类表示Internet协议(IP)地址
public class Class01_IP {
public static void main(String[] args) throws UnknownHostException {
InetAddress address1 = InetAddress.getLocalHost();
System.out.println(address1);
System.out.println(address1.getHostName());
System.out.println(address1.getHostAddress());
InetAddress address2 = InetAddress.getByName("www.baidu.cn");
System.out.println(address2);
System.out.println(address2.getHostName());
System.out.println(address2.getHostAddress());
}
}
2.端口
? 区分软件
端口 : 区分软件
端口号 2个字节 0~65535
同一协议下端口号不能冲突
建议使用8000以上的,8000以下称为预留端口好
常见的端口:
80 : http
8080 : tomcat
1521 : Oracle
3306 : Mysql
InetSocketAddress 此类实现IP套接字地址(IP地址+端口号)它也可以是一对(主机名+端口
public class Class02_Port {
public static void main(String[] args) {
InetSocketAddress in = new InetSocketAddress("localhost",8989);
System.out.println(in);
System.out.println(in.getHostName());
System.out.println(in.getPort());
}
}
3.URL
? 同一资源定位符,指向万维网上的“资源”的指针。
组成:
协议: http
域名: www.baidu.com
端口号: 80
资源: index.html
提交数据: name=zhangsan&pwd=123
锚点: #a
互联网 的三大基石:
html
http
url
URL 类
public class Class03_URL {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("https://www.baidu.com:80/index.html?name=zhangsan&pwd=123#a");
System.out.println(url);
System.out.println("协议:"+url.getProtocol());
System.out.println("域名:"+url.getHost());
System.out.println("端口:"+url.getPort());
System.out.println("资源:"+url.getFile());
System.out.println("资源:"+url.getPath());
System.out.println("资源:提交数据"+url.getQuery());
System.out.println("资源:锚点"+url.getRef());
}
}
二、UDP协议
1.套接字
传输层为应用层开辟的小口子
不同协议下Socket实现不同
UDP与TCP协议对Socket实现
2.UDP与TCP区别
UDP : 相当于写信|有包裹|发短信 非面向连接 协议简单,开销小,效率高 不安全 大小由限制(一般不超过60k)
TCP : 相当于打电话 面向连接 效率低 安全 大小没有限制
基于三次握手
3.UDP概念
UDP协议下发送端与接收端两端平等
DatagramSocket 此类表示用于发送和接收数据报包的套接字。
DatagramSocket(int port) 构造一个数据报套接字并将其绑定到本地主机上的指定端口。
void receive(DatagramPacket p) 从此套接字接收数据报包。
void send(DatagramPacket p) 从此套接字发送数据报包。
DatagramPacket 该类表示数据报包。
byte[] getData() 返回数据缓冲区。
int getLength() 返回要发送的数据的长度或接收的数据的长度。
数据的传输基于字节数组
UDP实现发送端: 基本流程
1.定义我是发送端
2.准备数据
3.打包
4.发送
5.关闭
4.例题
1)发送端
public class Class01_Send {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
DatagramSocket s = new DatagramSocket(9090);
System.out.println("-------------我是发送端-------------");
String str = sc.next();
byte[] arr = str.getBytes();
DatagramPacket packet = new DatagramPacket(arr,0,arr.length,new InetSocketAddress("192.168.16.9",8977));
s.send(packet);
s.close();
}
}
2)接收端
public class Class02_Receive {
public static void main(String[] args) throws IOException {
DatagramSocket r = new DatagramSocket(8989);
System.out.println("-----------我是接收端------------");
byte[] arr = new byte[1024];
DatagramPacket packet = new DatagramPacket(arr,arr.length);
r.receive(packet);
byte[] newArr = packet.getData();
int len = packet.getLength();
System.out.println(new String(newArr,0,len));
r.close();
}
}
三、TCP协议
1.概念
客户端 Socket
Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。
InputStream getInputStream()
OutputStream getOutputStream()
服务器 ServerSocket 该类实现服务器套接字。
ServerSocket(int port) 创建绑定到指定端口的服务器套接字。
Socket accept() 侦听对此套接字的连接并接受它。
tcp协议下传输数据基于IO流
tcp协议实现基本流程 : 客户端
1.定义我是客户端-->指定要请求的服务器的IP+端口
2.准备数据
3.获取输出流
4.输出-->IO操作
5.刷出
6.关闭
2.例题
例题1-1)客户端
public class Class01_Client {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("----------我是客户端----------");
Socket client = new Socket("192.168.16.9",8888);
System.out.println("与服务器建立连接成功");
String str = sc.next();
DataOutputStream os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
os.writeUTF(str);
os.flush();
sc.close();
os.close();
client.close();
}
}
1-2)服务器端
public class Class02_Server {
public static void main(String[] args) throws IOException {
System.out.println("---------我是服务器端---------");
ServerSocket server = new ServerSocket(8996);
Socket client = server.accept();
System.out.println("一个客户端连接成功");
DataInputStream is = new DataInputStream(new BufferedInputStream(client.getInputStream()));
String msg =is.readUTF();
System.out.println(msg);
is.close();
client.close();
server.close();
}
}
例题2-1)实现多线程登录(服务器端)
public class Class008_MulLoginTwoWayServer {
public static void main(String[] args) throws IOException {
System.out.println("--------我是服务器-------");
ServerSocket server = new ServerSocket(9898);
boolean flag = true;
while(flag){
Socket client = server.accept();
System.out.println("一个客户端连接成功........");
new Thread(new Channel(client)).start();
}
server.close();
}
static class Channel implements Runnable{
private Socket client = null;
private DataInputStream is = null;
private DataOutputStream os = null;
public Channel(Socket client) {
this.client = client;
try {
is = new DataInputStream(client.getInputStream());
os = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public String read(){
String msg = null;
try {
msg = is.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
public void write(String msg){
try {
os.writeUTF(msg);
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void close(){
if(os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(client!=null){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
String msg = read();
String username = null;
String password = null;
String[] strs = msg.split("&");
for(String s:strs){
String[] arr = s.split("=");
if("username".equals(arr[0])){
username = arr[1];
}else if("password".equals(arr[0])){
password = arr[1];
}
}
if("laopei".equals(username) && "1234".equals(password)){
write("登录成功");
}else{
write("登录失败");
}
close();
}
}
}
2-2)客户端
public class Class05_LoginTwoWayClient {
public static void main(String[] args) throws IOException {
System.out.println("--------我是客户端---------");
Socket client = new Socket("localhost",8989);
BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String username = rd.readLine();
System.out.println("请输入密码:");
String password = rd.readLine();
DataOutputStream os = new DataOutputStream(client.getOutputStream());
os.writeUTF("username="+username+"&password="+password);
os.flush();
DataInputStream is = new DataInputStream(client.getInputStream());
System.out.println(is.readUTF());
is.close();
os.close();
rd.close();
client.close();
}
}
例题3-1)实现文件上传(客户端)
public class Class01_Test1Client {
public static void main(String[] args) throws IOException {
System.out.println("--------客户端-------");
Socket client = new Socket("localhost",8787);
OutputStream os = client.getOutputStream();
BufferedInputStream is = new BufferedInputStream(new FileInputStream("C:\\Users\\27377\\Pictures\\20200817134947_obuqi.jpg"));
byte[] car = new byte[1024];
int len;
while ((len=is.read(car))!=-1){
os.write(car,0,len);
System.out.print("["+len+"] ");
}
os.flush();
os.close();
is.close();
}
}
3-2)服务器端
|