网络编程基础
网络中要素:
- IP地址和端口号
- 网络通信协议 udp tcp
IP
ip地址:InetAdress
- ip地址分类:
– ipv4 : 127.0.0.1 , 4个字节组成 0-255 42亿个,2011年用尽;
– ipv6 : 128位 8个无符号整数
IP分公网(互联网)和内网(局域网)
公网:分ABCD类
内网:192.168.xx.xx
Java中有InetAdress类提供方法能够查询IP 例如getByName()方法
端口
端口表示一个计算机上的进程
被规定为 0 ~ 65535
TCP/UDP 两个协议 各有 0~65535 两个协议不冲突,单个协议下端口冲突
端口分类
公用端口: 0-1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
程序注册端口:1024-49151,分配用户或程序
- Tomcat:8080
- MySQL:3306
动态、私有:49152-65535,程序不要用这里的
通信协议
协议:约定,就好比我们现在说的是普通话
网络通信协议: 速率,传送码率,代码结构,传输控制……
TCP/IP协议族
重要:
- TCP:用户传输协议
- UDP:用户数据报协议
出名的协议
- TCP:
- IP:网络互连协议
TCP UDB对比
TCP:像打电话
- 连接,稳定
- 三次握手,四次挥手
最少需要三次,才能稳定连接!
- 客户端,服务器
UDP:发短信
- 不连接,不稳定
- 客户端、服务器:没有明确的接线
- 不管有没有准备好,都可以发给你
- DDOS: 洪水攻击!(饱和攻击)
TCP
需要在Java上进行ServerSocket的套接编程来进行文件传输
服务端:进行端口声明
客户端:进行端口连接
服务端:serverSocket.accept()监听到客户端的socket
客户端:服务端的端口Output流中传出数据流(IO)
服务端:取到客户端socket中的Input流(IO)
服务端与客户端close()资源
//1创建一个socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
//2创建一个输出流
OutputStream os = socket.getOutputStream();
//3文件流
FileInputStream fis = new FileInputStream(new File("qinjiang.jpg"));
//4写出文件
byte[] buffer = new byte[1024];
int len;
while((len=fis.read(buffer))!= -1){
os.write(buffer,0,len);
}
os.close();
fis.close();
socket.close();
UDP
客户端发送包给服务器端即可
//1建立一下Socket
DatagramSocket socket = new DatagramSocket();
//2建包
String msg = "传输数据";
//发送给谁
InetAddress local = InetAddress.getByName("localhost");
int port = 9000;
//数据,数据的长度起始,发送给谁(消息字节,起,止,ip,端口)
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,local,port);
//发送包
socket.send(packet);
//关闭流
socket.close();
服务端接收客户端
//1建立一下Socket
DatagramSocket socket = new DatagramSocket();
byte[] buffer = new byte[1024];
new DatagramPacket(buffer,0,buffer.length);
//发送包
socket.receive(packet);
sout(packet.getAdress().getHostAdress());//获取IP
sout(new String(packet.getData(),0,packet.getLength()))//获取内容转字符串
//关闭流
socket.close();
扩展:多线程通信聊天
配置发送线程类
public class TalkSend implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
private Integer fromPort;
private String toIp;
private Integer toPort;
public TalkSend(Integer fromPort, String toIp, Integer toPort) {
this.fromPort = fromPort;
this.toIp = toIp;
this.toPort = toPort;
try {
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
String data = null;
try {
data = reader.readLine();
byte[] bytes = data.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(this.toIp, this.toPort));
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
if("bye".equals(data)){
break;
}
}
socket.close();
}
}
配置聊天接收线程类
public class TalkReciver implements Runnable {
DatagramSocket socket = null;
private String msgFrom;
public TalkReciver(Integer port,String msgFrom) {
this.msgFrom = msgFrom;
try {
socket= new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
DatagramPacket packet = null;
try {
//准备接收包裹
byte[] container = new byte[1024];
packet = new DatagramPacket(container,0,container.length);
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
byte[] data = packet.getData();
String reciverData = new String(data, 0, data.length);
System.out.println(msgFrom+":"+reciverData);
if("bye".equals(reciverData)){
break;
}
}
socket.close();
}
}
测试:模拟场景-学生和老师互相通信
学生角色:
public class TalkStudent {
public static void main(String[] args) {
// 7777 是学生发送线程的端口,9999是对方接收线程的端口
new Thread(new TalkSend(7777,"localhost",9999)).start();
// 8888是学生接收线程的端口
new Thread(new TalkReciver(8888,"老师")).start();
}
}
老师角色:
public class TalkTeacher {
public static void main(String[] args) {
new Thread(new TalkSend(5555,"localhost",8888)).start();
new Thread(new TalkReciver(9999,"学生")).start();
}
}
个人总结观点:
以上功能实现可抽象理解为:
学生和老师各 有一台只能接到短信的BP机,和一台只能发送短信的呼叫机
呼叫机有自己的号码,但是接收短信是需要发到BP机的号码上去
所以Sender的toPort是对方【接收线程】的Port ,fromPort则用于后台管理,跟对方向目标发送消息没有直接关系。
URL相关
https://www.baidu.com/
统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析 www.baidu.com 的本质还是 xxx.xx.x.xx 的IP
一个URL由五部分组成:【协议:// ip地址 : 端口 / 项目名 / 资源】
通过Java中的Url来下载网上资源
public static void main(String[] args) throws IOException {
//下载地址
//1定义地址
URL url = new URL("https://pics2.baidu.com/feed/1b4c510fd9f9d72a018e27c8c643f233369bbbe9.jpeg?token=21c4ee487e621fdf4432e25290a9eb6d&s=7587CAB69F192A51430B75AC0300E048");
//2 连接到这个url资源
HttpURLConnection urlConnection =(HttpURLConnection) url.openConnection();
//创建本项目的输入流
InputStream is = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("pic.jpg");
byte[] bytes = new byte[1024];
int len;
while((len = is.read(bytes)) != -1){
fos.write(bytes,0,bytes.length);// 2021/1/6 Bowen 写出数据;
}
System.out.println("sucess");
fos.close();
is.close();
urlConnection.disconnect();
System.out.println("closeOver");
}
salute Kuangshen