网络编程(套接字)
网络的七层模型:
物理层 数据链路层 网络层 传输层(udp、tcp) 会话层 表示层 应用层(http/https/ftp)
概述:
基于网络系统进行数据传输 UDP TCP
IP地址:
唯一标识网络中的通信实体
IPV4
32位二进制组成;分成4组,每组的范围0-255之间,每组之间通过.来分隔
例如:192.168.12.22
IPV6
128位二进制组成;分成了8组,每组16位,16进制;每一组由4个16进制数字组成;每组之间通过:分隔
IP不能重复
IP会不会变?–IP动态分配的过程,静态IP可以实现但是收费高昂;
端口号:
数据发送还是数据接收都需要通过端口号
给端口进行了一个编号:0-65535
0-1024 这些端口被系统内部或者通用协议已经占用
域名:
将IP地址通过一个字符串来代替
80:缺省端口
DNS:域名解析
提供根据域名查询IP地址服务
C:\Windows\System32\drivers\etc\hosts
SocketAddress:抽象类
实现: InetSocketAddress
该类实现了IP套接字地址(IP地址+端口号)它也可以是一对(主机名+端口号),在这种情况下,将尝试解析主机名。如果解决失败然后地址说是未解决的但仍可以使用在某些情况下,如通过代理连接。
import java.net.InetSocketAddress;
public class SocketAdressDemo {
public static void main(String[] args) {
//Inet SocketAdress对象 表示IP和端口
InetSocketAddress iss = new InetSocketAddress(
"127.0.0.1",3344);
//获取主机名
//127.0.0.1永远指向当前本机(localhost本机)
//如果是本机,则返回主机名,如果是其他机器,则返回传入的IP地址
System.out.println(iss.getHostName());
//获取端口号
System.out.println(iss.getPort());
}
}
UDP和TCP
UDP:
1、不建立连接
2、不可靠
3、数据传输效率高
应用场景:
对数据可靠性要求不太高,但是对数据传输效率要求比较高
例如:语音通话,视频通话 视频直播
如何使用UDP进行网络数据传输呢?
底层基于留实现,使用JDK提供的DatagramSocket
DatagramSocket:
这类代表一个发送和接收数据包的插座。
数据报套接字发送或者接收点的分组传送服务。每个发送的数据包或数据报套接字上接收单独寻址和路由。从一台机器发送到另一台机器的多个数据包可能会被不同的路由,并可以以任何顺序到达。
无参构造:构建一个数据报套接字绑定到本地主机的任何可用的端口。
DatagramSocket(int port)
构建一个数据报套接字绑定到本地主机的指定端口。
void send(DatagramPacket p)
从这个套接字发送数据报包。
void receive(DatagramPacket p)
接收数据报包从这个插座。
DatagramPacket :这类表示一个数据报包。
构造方法:
接收:DatagramPacket(byte[] buf, int length)
接收数据包长度 length DatagramPacket构建。
发送:DatagramPacket(byte[] buf, int length, SocketAddress address)
指定主机上的指定端口发送数据包的长度 length数据报包结构。
发送端:
指定:IP+端口
1、创建发送端的对象DatagramSocket
2、准备数据包DatagramPacket
3、调用方法发送数据
4、关流
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class UDPSenderDemo {
public static void main(String[] args) throws IOException {
//创建发送端DatagramSocket对象
DatagramSocket ds = new DatagramSocket();
//准备数据包DatagramPacket
//第一个参数:byte[]buf表示要发送的数据
//第er个参数:发送的长度
//第三个参数:SocketAddress--InetSocketAddress
String str = "helloword";
byte[] bytes = str.getBytes();
InetSocketAddress isa = new InetSocketAddress(
"127.0.0.1",3456);
DatagramPacket dp = new DatagramPacket(bytes,
bytes.length,isa);
//调用方法发送数据
ds.send(dp);
//关流
ds.close();
}
}
接收端:
指定:监听端口号
1、创建接受端的对象DatagramSocket并指定端口号
2、准备接受数据的数据报包DatagramPacket
3、调用接受数据的方法
4、关流
5、解析数据报包,并打印接受到的内容
package cn.ppenggs.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* 此案例是UDP的接收端
*/
public class UDPReceiverDemo {
public static void main(String[] args) throws IOException {
//1创建接受端的DatagramSocket对象,并指定端口
DatagramSocket ds = new DatagramSocket(3456);
//2准备接受数据的数据报包DatagramPacket
//第一个参数 指定一个byte数组,用于接收数据
//第二个参数 指定数组可以使用的长度,byte数组
DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
//3调用接受数据的方法
ds.receive(dp);
//4关流
ds.close();
//5解析数据报包,并打印接受到的内容
byte[] data = dp.getData();
System.out.println(new String(data,0,dp.getLength()));
}
}
单人聊天,结合多线程:
发送端的数据获取用户输入的数据
接收端不断的接收发送端发过来的数据并打印
1、分别创建发送端和接收端的类 实现Runnable接口
2、实现run方法
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;
/**
*
*/
public class ChatUDPDemo {
public static void main(String[] args) {
//创建线程对象
new Thread(new ChatSender()).start();
new Thread(new ChatReceiver()).start();
}
}
//定义发送端的类 实现Runnable接口
class ChatSender implements Runnable{
@Override
public void run() {
//定义udp发送数据的类
try {
DatagramSocket ds = new DatagramSocket();
//准备scanner 输入数据
Scanner scanner = new Scanner(System.in);
while (true){
String msg = scanner.next();//阻塞--不断获取用户输入的字符串
//创建数据报包
DatagramPacket dp = new DatagramPacket(msg.getBytes(),msg.length(),
new InetSocketAddress("127.0.0.1",6666));
//发送数据
ds.send(dp);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//定义接收端的类 实现Runnable接口
class ChatReceiver implements Runnable{
@Override
public void run() {
//接收端的类
try {
DatagramSocket ds = new DatagramSocket(6666) ;
while (true){
//准备接收数据的数据报包
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
//接收数据---阻塞
ds.receive(dp);
//解析数据
byte[] msg = dp.getData();
System.out.println(dp.getAddress()+":"+ new String(bytes,0,dp.getLength()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
TCP
1、建立连接(三次握手)
2、可靠的
3、数据传输效率低
4、不限制传输数据量
应用场景:
数据可靠性要求高,对数据传输效率没有特别高的要求
例如:文件传输