什么是计算机网络
把分布在不同地理区域的计算机设备,通过通信设备和线路(网线,光纤,交换机)连接,最终实现数据的传输和资源的共享。
实现不同计算机之间的联系,必须有介质连接
最早的网络:美国五角大楼一间办公室,后来一栋楼,然后一个城市,一个国家,全球
网络编程
在网络的基础上,开发的程序能够进行数据传输
Java语言是支持网络的
Java语言将网络连接的细节都封装起来了,对外提供一套网络库(类),就可以进行统一环境的网络编程
进行网络数据传输的核心问题
1.如何找到网络世界中的目标主机和程序(IP和端口)
2.找到后如何高效安全的进行数据传输(协议)
网络模型
应用层
QQ,微信等
传输层
加入协议控制
网络层
IP 协议控制
物理层
网线 光纤
三要素:IP地址 端口 协议
IP(Internet Protocol Address)
是指互联网协议地址,计算机的地址
电脑地址在命令提示符中输入 ipconfig 查找
局域网ip 192.168.
本机回环地址 127.0.0.1 访问自己电脑
端口
计算机中运行的每个程序都对应分配一个整数编号,不能重复
0~1024系统使用或保留的端口 0~65535为有效的端口号
协议(规则 规范 约定)
规定传输的速率,代码结构,出错后如何应对等等规则
java中的两种协议下的编程
TCP
传输控制协议TCP(Transmission Control Protocol)
客户端向服务器端发送数据前,首先要建立连接(测试网络是否通畅)
三次握手机制
正式传输数据
传输完毕,需释放已建立的连接,效率低
断开时还要相互确认
四次挥手
特点:可靠安全,但是效率相对于UDP较低
三次握手
步骤:
1.客户端向服务器端发送链接请求
2.当服务器收到客户端链接请求后,给客户端做出一个回应
3.客户端为服务器的回应做出确认回应
4.开始传输数据
四次挥手
步骤:
1.客户端向服务器端发送断开请求
2.服务器向客户端做出一个回应
3.服务器把没有传完的数据传输完毕,再向客户端做出回应
4.客户端向服务器端回应做出回应
5.断开
UDP
用户数据报协议UTP(User Datagram Protocol)
把要发送的数据封装成一个数据报(数据包),数据包包含数据,对方的ip,对方端口。
只管发送即可,是否发送成功是不知道的
特点:是不可靠的,但传输效率高
标志位
URG:紧急指针有效;
ACK:确认序号有效;
PSH:接收方应该尽快将这个报文交给应用层;
RST:重置连接;
SYH:发起一个新连接;
FIN:释放一个连接;
TCP编程和UDP编程
TCP编程
服务器程序的工作过程包含以下四个基本的步骤:
调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。
服务器
服务器必须事先建立一个等待客户请求建立套接字连接的ServerSocket对象
ServerSocket serverSocket = new ServerSocket(52013);
52013:端口,须在1024到65535之间
传输方法
字节流
IntputStream
OutputStream
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(52013);
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("服务器启动失败,端口已被占用");
}
}
}
包装流 能直接读到一个字符串
DataIntputStream
DataOutputStream
public class Server {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
ServerSocket serverSocket = new ServerSocket(9810);
System.out.println("服务器启动成功!");
//监听客户端是否发送链接请求到服务器
Socket socket = serverSocket.accept();//阻塞了,监听客户端的连接
System.out.println("有客户端连接到服务器");
while (true){
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
String s = dataInputStream.readUTF();
System.out.println(s);
//从服务器向客户端发送信息
String s1 =scanner.next();
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(s1);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败,端口已被占用");
}
}
}
客户端
Socket socket = new Socket("127.0.0.1",52013);
"127.0.0.1":IP地址,连接网络不同时会产生不同的IP地址,127.0.0.1 是主机回环地址
50213:端口,需要与创建的服务器端口相同
传输方法
字节流
IntputStream
OutputStream
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1",52013);
String s = "你干嘛~哈哈~哎哟";
OutputStream outputStream = socket.getOutputStream();
outputStream.write(s.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
包装流 能直接读到一个字符串
DataIntputStream
DataOutputStream
public class Client {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
Socket socket = new Socket("127.0.0.1",9810);
while (true){
//向服务器传输信息
String s = scanner.next();
/*OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);*/
//可简化为
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(s);
//接收服务器传输的信息
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
String s1 = dataInputStream.readUTF();
System.out.println(s1);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP编程
流 程:
1. DatagramSocket与DatagramPacket
2. 建立发送端,接收端
3. 建立数据报
4. 调用Socket的发送、接收方法
5. 关闭Socket
发送端与接收端是两个独立的运行程序
发送端
import java.io.IOException;
import java.net.*;
public class UdpSend {
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"),6666);
datagramSocket.send(datagramPacket);
//datagramSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接收端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpReceive {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket = new DatagramSocket(6666);
//封装一个数据报对象,用来接收数据
byte[] bytes = new byte[100];//用来分装数据
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
datagramSocket.receive(datagramPacket);//真正的接收数据
// 实际接收到的数据长度
String s = new String(datagramPacket.getData(),0,datagramPacket.getLength());
System.out.println(s+"——"+datagramPacket.getAddress());
}catch (IOException e) {
e.printStackTrace();
}
}
}