目录
传输控制协议TCP(Transmission Control Protocol)
用户数据报协议UDP(User Datagram Protocol)
网络编程概述
什么是计算机网络
将分布在不同地理区域的具有独立功能的计算机(广义上的)通过通信设备和线路连接起来,可以实现数据的传输和共享的系统。
要实现不同的计算机之间的联系,必须有介质连接。
最开始一间办公室-->一栋楼-->一个城市-->一个国家-->全球
网络编程是干什么
聊天--->聊天软件 QQ
java语言是支持网络间的数据传输的,将底层的细节都封装起来,给程序员一套标准的类库,我们可以很方便的使用java语言开发出可以进行网络通信的软件。
网络编程目的
借助计算机网络,实现我们所写的程序,在不同的电脑上可以进行数据的传输
网络编程核心问题
如何找到网络世界中的目标主机,以及目标软件
win+r cmd ipconfig 查看自己电脑的ip.
如何安全可靠的进行数据传输
协议 规则
网络模型
OSI参考模型,是一个理想化的标准模型 分成七层
实际上的使用Tcp/Ip网络模型 分为四层
应用层(http)
运输层(协议)
网络层(IP)
物理链路层(硬件设备)
网络传输数据为什么要分层
在不同的层中,对数据加入不同的头(协议,IP)
逐层分工处理
网络通信要素:IP,端口号,通信协议
目标主机,以及目标软件
IP:
在网络世界中,是计算机的地址()
局域网地址:
192.168.1.20连接到路由器会自动分配ip
广域网地址:
家里的宽带 与外界连接
本机地址:
本地回环地址 127.0.0.1
端口:
是计算机中运行中的程序的编号,对应的是运行中的程序
IP找主机,端口找程序
IP+端口 找到目标计算机 已经你想要的程序
端口号0-65535之间 由于0-1024被一些系统程序使用,所以我们开发的程序可以从1024-65535区间定义,但是不能与已有的端口冲突。
如何安全运输--通信协议
为了安全可靠的进行数据传输,需要对传输的内容,速率,出错之后的处理办法进行控制而制定的一些规约,称为协议。传输层有两个主要的协议:
传输控制协议TCP(Transmission Control Protocol)
使用TCP协议进行数据传输前,必须先要检测网络是否通畅,客户端是否能连接到服务器端,如果能连接到,则进项数据的传输,如果连接不到,会报错。采用的是三次握手的机制。
tcp是可靠的,相对udp效率低
三次握手
1、第一次客户端给服务器端发送一个信息,确认服务器端是否可以进行数据传输;
2、服务器端收到客户端的请求后,回复客户端可以进行数据传输;
3、客户端收到服务器端的确认反馈后,再一次向服务器端发送一个反馈,以确保服务器端指找到客户端收到了他的反馈。
四次挥手
1、客户端向服务器端发送一个断开的请求
2、服务器端向客户端做出一个反馈
3、服务器端把没有发完的数据全部发送给客户端
4、客户端最后再向服务器端发送一个最终的断开信号
用户数据报协议UDP(User Datagram Protocol)
将数据封装成一个一个数据报
数据报包含 数据 源(自己电脑ip) 目标(接收端ip 端口 )
发送前不需要建立连接,只管发送,是否成功,不知道
是不安全的,但是效率高
java中是两种协议下的编程
TCP编程
利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为 事实上的标准。
通信的两端都要有Socket,是两台机器间通信的端点
网络通信其实就是Socket间的通信。
Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
一次性
代码
package com.ffyc.javanetwork.tcpdemo.demo1;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args){
try {
//创建并启动服务器
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务器启动成功");
//监听有没有客户端连接到服务器,监听时会阻塞程序
Socket socket = serverSocket.accept();
System.out.println("有客户端连接到了服务器");
//接收客户端发送的数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[100];
int size = inputStream.read(bytes);
String s = new String(bytes, 0, size);
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败,端口被占用");
}
}
}
package com.ffyc.javanetwork.tcpdemo.demo1;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
//创建客户端
try {
Socket socket = new Socket("127.0.0.1", 9999);
//在客户端向服务器端发送一句话
OutputStream outputStream = socket.getOutputStream();
String s = "你好";
outputStream.write(s.getBytes());
} catch (IOException e) {
e.printStackTrace();
System.out.println("连接服务器失败");
}
}
}
运行
可循环
代码
package com.ffyc.javanetwork.tcpdemo.demo2;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(9999);
//监听
Socket socket = serverSocket.accept();
while (true){
//接收客户端发送的内容
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
String s1 = dataInputStream.readUTF();
System.out.println("客户端说:"+s1);
//服务器端向客户端挥发一个消息
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
Scanner scanner = new Scanner(System.in);
System.out.println("服务器端输入:");
String s2 = scanner.next();
dataOutputStream.writeUTF(s2);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.ffyc.javanetwork.tcpdemo.demo2;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 9999);
while (true){
OutputStream outputStream = socket.getOutputStream();
//数据处理流,直接可以输出字符串
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
Scanner scanner = new Scanner(System.in);
System.out.println("客户端输入:");
String s1 = scanner.next();
dataOutputStream.writeUTF(s1);
//接收服务器发送的消息
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
String s2 = dataInputStream.readUTF();
System.out.println("服务器端说:"+s2);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行
UDP编程
类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP 数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址 和端口号以及接收端的IP地址和端口号。
UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方 的连接
接收端
package com.ffyc.javanetwork.udpdemo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Receive {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket = new DatagramSocket(9999);
//封装一个数据报对象用来接收数据
byte[] bytes = new byte[100];//用来分装数据的
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length);
//真正的接收数据
datagramSocket.receive(datagramPacket);
//实际接收到的数组的长度
String s = new String(bytes, 0, datagramPacket.getLength());
System.out.println(s);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
一次性
发送端
package com.ffyc.javanetwork.udpdemo;
import java.io.IOException;
import java.net.*;
public class Send {
public static void main(String[] args) {
//负责发送数据
try {
DatagramSocket datagramSocket = new DatagramSocket();
//发送的数据
byte[] bytes = "你好接收端".getBytes();
//封装一个数据报
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length,InetAddress.getByName("127.0.0.1"),9999);
datagramSocket.send(datagramPacket);
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行
可循环
发送端
package com.ffyc.javanetwork.udpdemo;
import java.io.IOException;
import java.net.*;
public class Send {
public static void main(String[] args) {
//负责发送数据
try {
DatagramSocket datagramSocket = new DatagramSocket();
while(true){
//发送的数据
byte[] bytes = "你好接收端".getBytes();
//封装一个数据报
DatagramPacket datagramPacket = new
DatagramPacket(bytes,0,bytes.length,InetAddress.getByName("127.0.0.1"),9999);
datagramSocket.send(datagramPacket);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}