网络编程
概述:
TCP概念类似于:打电话-连接-接了-通话
UDP概念类似于:发短信-发送了就结束了-接收
计算机网络:计算机网络系统就是利用通信设备和线路将地理位置不同、功能独立的多个计算机系统互联起来,以功能完善的网络软件实现网络中资源共享和信息传递的系统。
网络编程的目的:传播交流信息
想要达到这个效果需要什么
1.如何准确的定位网络上的一台主机:ip:端口+定位到此计算机上的某个资源
2.找到这个主机,如何传输数据?
javaweb:网页编程 B/S
网络编程:TCP/IP C/S
网络通信的要素
如何实现网络的通信?
通信双方的地址:ip+端口
规则:网络通信协议
重点:
IP
ip地址:InetAddress
唯一定位一台网络上计算机
127.0.0.1:本机localhost
ip地址的分类:1.ipv4/ipv6
ipv4 :127.0.0.1 4字节组成,0~255
ipv6 :win+R cmd ipconfig,128位,8个无符号数
公网(互联网)——私网(局域网)
ABCD类地址
192.168.xx.xx是专门给组织内部使用的
栗子:
import java.net.InetAddress;
import java.net.UnknownHostException;
//测试ip
public class studyip {
public static void main(String[] args) throws UnknownHostException {
try {
//查询本地地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
//查询网站地址
InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");//获取网站的ip地址
System.out.println(inetAddress2);
InetAddress bilibili = InetAddress.getByName("www.bilibili.com");
System.out.println(bilibili);
//
System.out.println(localHost.getHostName());//域名
System.out.println(localHost.getHostAddress());//ip
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口
端口表示计算机上的一个程序的进程
不同的进程有不同的端口号,用来区分软件
被规定0~65535
TCP,UDP 65535*2 两端口不能相同,单个协议下端口不能冲突
端口分类:
公有端口0~1023
HTTP:80
HTTPS:443
FTP:21
Telent:23
程序注册端口:1024~49151,分配给用户或者程序
Tomcat:8080
MySQL:3306
Oracle:1521
动态、私有:49152~65535
win+R cmd 然后
netstat -ano#查看所有端口
netstat -ano|findstr "端口号"#查看指定端口
tasklist|findstr "端口号"#查看指定端口进程
#任务管理器pid为端口号
import java.net.InetSocketAddress;
public class testInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
System.out.println(inetSocketAddress1);
System.out.println(inetSocketAddress2);
//============================================
System.out.println(inetSocketAddress1.getAddress());//ip地址
System.out.println(inetSocketAddress1.getPort());//端口
System.out.println(inetSocketAddress1.getHostName());//域名
}
}
通信协议
网络通信协议:速率,传输码率,代码结构,传输控制
TCP/IP协议簇:两个重要协议:
TCP:用户传输协议,连接,稳定,传输完成后释放连接,效率低,“三次握手”
UDP:用户数据报协议,不连接,不稳定
DDos:分布式拒绝服务攻击
TCP
客户端:1.连接服务器Socket 2.发送消息
package net;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class TcpClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {//需要有服务器的地址
InetAddress byName = InetAddress.getByName("127.0.0.1");
//需要有一个端口号
int port = 9999;
//创建一个Socket连接
socket = new Socket(byName,port);
//发送消息,IO流
outputStream = socket.getOutputStream();
outputStream.write("test测试,向服务器发送数据,test".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
服务器:1.建立服务端口 2.等待用户连接accept 3.接受用户消息
package net;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.io.IOException;
import java.net.Socket;
//服务器
public class TcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;//提优先级
Socket accept = null;
InputStream inputStream = null;
ByteArrayOutputStream baos = null;
try { //首先需要有一个地址
serverSocket = new ServerSocket(9999);
//等待客户端连接过来
accept = serverSocket.accept();
//读取客户端的消息
inputStream = accept.getInputStream();
//管道流
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];//缓冲区
int len;
while ((len=inputStream.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (baos!=null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (accept!=null){
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
上传文件:
以图片test.jpg为例,传输完成后服务器接收的为receive.jpg
客户端:
package net2;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
//客户端,图片传输相关
public class TcpClient {
public static void main(String[] args) throws Exception{
//创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9998);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("untitled/test.jpg"));
//写出文件
byte[] buffer =new byte[1024];//缓冲区
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
//通知服务器已经传输结束
socket.shutdownOutput();
//接收服务器的关闭信息
InputStream is = socket.getInputStream();//接收服务器反馈的信息
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[2014];
int len2;
while ((len2=is.read(buffer2))!=-1){
baos.write(buffer2,0,len2);
}
System.out.println(baos.toString());
//关闭文件
fis.close();
os.close();
socket.close();
}
}
服务器:
package net2;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class TcpServer {
public static void main(String[] args)throws Exception {
//创建服务器
ServerSocket serverSocket = new ServerSocket(9998);
//监听客户端的连接
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
//
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
//
OutputStream os = socket.getOutputStream();
os.write("接收完毕,可以断开".getBytes());
//关闭
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
Tomcat
服务端:自定义 S (Server的缩写)、Tomcat服务器 S:Java后台开发
客户端:自定义 C (Client的缩写)、浏览器B
UDP
发送包&接收包
发送的内容为hello,Server
客户端:
package net3;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args) throws Exception{
//建立一个Socket
DatagramSocket socket = new DatagramSocket();
String msg="hello,Server";//发送的信息
InetAddress localhost = InetAddress.getByName("localhost");//域名
int port=9090;//端口
//信息、起始位置、结束位置、域名、端口
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
//发送包
socket.send(packet);
//关闭流
socket.close();
}
}
服务器:
package net3;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer {
public static void main(String[] args) throws Exception{
DatagramSocket socket = new DatagramSocket(9090);//新建一个Socket
byte[] buffer = new byte[1024];//缓冲区
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);//阻塞接收
System.out.println(packet.getAddress().getHostAddress());//打印接收到的包的发送地址
System.out.println(new String(packet.getData(),0,packet.getLength()));//打印接收到的包的信息
//关闭连接
socket.close();
}
}
实时的单向发送消息
发送者:
package chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
public class UDPSender {
public static void main(String[] args)throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据,控制台读取System.in
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String data = reader.readLine();
byte[] datas = data.getBytes();//数据是不可读的,需要先转成字节
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
if (data.equals("bye")){
break;
}
//发送包
socket.send(packet);
}
//关闭流
socket.close();
}
}
接收者:
package chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPRecevicer {
public static void main(String[] args) throws Exception{
DatagramSocket socket = new DatagramSocket(6666);//新建一个Socket
while (true) {
//准备接收包裹
byte[] container = new byte[1024];//缓冲区
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
socket.receive(packet);//阻塞接收
//断开连接:bye
byte[] data = packet.getData();
String s = new String(data, 0, packet.getLength());
System.out.println(s);
if (s.equals("bye")){//如果接收到bye,则结束循环
break;
}
}
//关闭连接
socket.close();
}
}
学习多线程后将完成实时通信
URL
统一资源定位符:定位本地资源或定位互联网上的某一资源
DNS域名解析 www.baidu.com xxx.x…x…x数字ip
组成URL的五部分:
协议://ip地址:端口/项目名/资源
五部分可以少但是不能多
package net4;
import java.net.MalformedURLException;
import java.net.URL;
public class UrlDemo {
public static void main(String[] args) throws MalformedURLException {//需要用到Tomcat
URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=Dove&passord=123");
System.out.println(url.getProtocol());//获取协议
System.out.println(url.getHost());//获取ip
System.out.println(url.getPort());//获取端口
System.out.println(url.getPath());//获取全路径
System.out.println(url.getFile());//获取文件
System.out.println(url.getQuery());//获取参数
}
}
URL下载:
package net4;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class UrlDownLoad {
public static void main(String[] args)throws Exception {
//网页地址
URL url = new URL("https://m801.music.126.net/20210805143325/5051caa0b0dcf1a097a98beb78e45463/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/8775906482/e356/02c7/04b1/e315fd4dc7462cbf7089d48b78a213f3.m4a");
//链接到这个地址http
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream is = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("test2.m4a");//输出什么文件填对应类型
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.close();
is.close();
urlConnection.disconnect();
}
}
//这里下载的是牛尾憲輔的乒乓OSTLike a dance