1、网络编程
1.1、概述
- 计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备;通过通信线路和通信设备连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
- 网络编程的目的:网络编程的主要目的是直接或间接地通过网络协议与其他计算机实现数据交换,进行通信。
- 想要带到这个效果需要什么:
- 是如何准确地定位网络上的主机
- 是找到主机后如何可靠高效地进行数据传输。
javaweb : 网页编程 B/S架构(浏览器访问)
网络编程 : TCP/IP C/S架构(客户端)
1.2、网络通信的要素
IP地址:IP地址是设备在网络中的唯一标识,它允许设备在互联网上进行通信。IP地址分为IPv4和IPv6两种形式,其中IPv4地址由32位组成,而IPv6地址由128位组成,提供了更大的地址空间。IPv6的设计旨在为地球上的每一粒沙子分配一个独特的地址。IP地址分为公网IP和私有地址(局域网使用),其中192.168.开头的地址是常见的局域网地址范围。特殊IP地址如127.0.0.1或localhost被称为回送地址,用于本地回环测试。
传输设备:传输设备为信息的传输提供传输信道,并将网络节点连接在一起。这些设备包括线路接口设备、传输媒介和穿插连接设备等,它们共同构成了通信网络的基础设施,确保信息能够有效地从一个地点传输到另一个地点。
交换设备:交换设备是现代通信网的核心,它完成信号的交换、节点链路的汇集、转接和分配。交换设备的存在使得通信网络能够灵活地处理大量的数据传输请求,是实现高效通信的关键因素。
TCP/IP参考模型
1.3、总结
-
网络编程的两个主要问题
- 如何准确的定位到网络上的一台或多台主机(通过ping域名查看IP,www.baidu.com)
- 找到主机之后如何进行通信
-
网络百年城中的要素
- IP和端口号
- 网络通信协议
-
万物皆对象--学习类
- IP和端口号 学IP类
- 网络通信协议 学udp , tcp
2、IP、端口Port、通信协议
2.1IP类
IP地址:InetAddress
唯一定位一台网络计算机
- 127.0.0.1:本机的localhost
- IP地址分为公网IP和私有地址(局域网使用),其中192.168.(专门给组织内部使用)开头的地址是常见的局域网地址范围。特殊IP地址如127.0.0.1或localhost被称为回送地址,用于本地回环测试。
IP地址的分类
-
IPV4/IPV6
- IP地址分为IPv4和IPv6两种形式,其中IPv4(4个字节)地址由32位组成,而IPv6地址由128位组成,提供了更大的地址空间。IPv6(8个无符号整数)的设计旨在为地球上的每一粒沙子分配一个独特的地址。
-
域名(诞生为了解决IP问题!)
- IP:好的域名非常的贵(越短越贵) www.jd.com www.vip.com com国际,cn中国
package intIp;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
//测试IP
public class testIntAddress {
public static void main(String[] args){
//AlT+回车选择try catch
//查询本机地址
try {
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);
System.out.println("localHost");
InetAddress inetAddress3 = InetAddress.getLocalHost();
System.out.println(inetAddress3);
//查询网站地址
InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress2);
//常用方法
System.out.println("=========常用方法===========");
System.out.println(inetAddress2.getCanonicalHostName());//获得规范域名即IP
System.out.println(inetAddress2.getHostAddress());//IP
System.out.println(inetAddress2.getHostName());//获得域名即电脑的名字
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}
2.2端口Port
端口表示计算机上一个程序的进程
-
不同的进程有不同的端口(用来区分软件)
-
被规定0-65535
-
TCP,UDP:65535*2,tcp:80,udp:80,单个协议下的端口不能冲突
-
端口分类
-
公有端口0-1023(一般被内置服务器使用,不要去占用)
-
Http:80
-
Https:443
-
FTP:21
-
Telent:23
-
-
程序注册端口1024-49151(分配给用户或者程序)
- Tomcat:8080
- MySQL:3306
- Oracle:1521
-
动态,私有:49152-65535
netstat -ano //查看所有的端口-在cmd中 netstat -ano|findstr "5900" //查看指定的端口 tasklist|findstr"8696" //查看指定端口的进程 Control+Shift+ESC //快捷键打开任务管理器
-
-
端口映射(没什么用) InetSocketAddress
package intIp; import java.net.InetSocketAddress; //端口映射 public class testIntSockedAd { public static void main(String[] args) { InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8081); System.out.println(inetSocketAddress); System.out.println(inetSocketAddress.getAddress());//IP System.out.println(inetSocketAddress.getPort());//端口 System.out.println(inetSocketAddress.getHostName());//地址 } }
2.3通信协议
协议相当于约定,就好比上课讲普通话
网络通信协议:速率、传输码率、代码结构、传输控制
问题:非常的复杂——通过大事化小—分层!
- TCP:用户传输协议
- UDP:用户数据协议
区别:
TCP(打电话)
-
连接,稳定
-
三次握手,四次挥手
最早至少需要三次才能确定建立连接,至少四次才能确定断开连接
A:你愁啥 B:瞅你咋地 A:干一场 A:我走了 B:我真的要走了吗 B:你真的走了吗 A:我真的要走了
-
客户端,服务端
-
传输完成,释放连接,效率低
UDP(发短信)
1. 不连接,不稳定
2. 客服端和服务端没有明确界限
3. 不管有没有准备好,都可以发出去
4. 导弹
5. DDOS :洪水攻击(饱和攻击)
注:出名的协议
TCP/IP协议,实际上是一组协议
- TCP
- IP:网络互联协议
3、TCP(InetAddress.getByName、ServerSocket、Socket)
3.1TCP实现聊天
客户端
服务端
package intIp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class TcpClientD1 {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
//1.要知道服务器的地址
InetAddress serverIP = InetAddress.getByName("localhost");//InetAddress,服务器IP(此电脑)
int port = 9999; //port 自己创建一个端口号
//2.创建一个socket连接
socket = new Socket(serverIP,port); //Socket客服端连接(Control可以查看源码),给服务端IP和端口,这里需要将异常做到最大Exception
//3.发送消息到 IO流
os = socket.getOutputStream(); //getOutputStream发出流
os.write("今天,再见".getBytes());
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
if (os != null) {
try{
os.close();
}catch (IOException e) {
throw new RuntimeException(e);
}
}
}if(socket != null){
try{
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);}
}
}
}
package intIp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class TcpServerD1 {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.得有个地址
serverSocket = new ServerSocket(9999);//ServerSocket服务端地址(插座)
while(true){//循环接收
//2.等待客户端连接过来
socket = serverSocket.accept(); //serverSocket.accept(); 监听是否连接过来,socket是一样的
//3.读取客户端的信息
is = socket.getInputStream();//getInputStream接受流
//4.管道流(转换流)-避免中文字节超出
baos = new ByteArrayOutputStream();//ByteArrayOutputStream字节数组输出流
byte[] buffer = new byte[1024];//byte[1024]字节数组
int len;
while((len=is.read(buffer))!=-1){//字节读取判断
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally{//socket需要关闭(先开后关原则);关闭一般在Finally中,需要提升作用域(关闭需要抛出异常-避免运行中断),前面进行if判断更安全
//关闭资源
if(baos!=null){
try{
baos.close();
}catch (IOException e) {
throw new RuntimeException(e);
}
}
if(is!=null){
try{
is.close();
}catch (IOException e) {
throw new RuntimeException(e);
}
}
if(socket!=null){
try{
socket.close();
}catch (IOException e) {
throw new RuntimeException(e);
}
}
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
3.2TCP文件上传(清爽版)
package intIp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClientD2 {
public static void main(String[] args) throws Exception {
//1.创建一个socket连接
Socket socket = new Socket(InetAddress.getByName("localhost"), 9000);
//2.创建一个输出流
OutputStream os = socket.getOutputStream();
//3.读取文件
FileInputStream fis = new FileInputStream(new File("C:\\院级优秀团员机械徐志磊卓越2002(生活委员)牟李旭\\志愿证书.jpg"));
//4.写出文件
byte[] buffer = new byte[1024];//byte[1024]字节数组
int len;
while((len=fis.read(buffer))!=-1){//字节读取判断
os.write(buffer,0,len);
}
//通知服务器,我已经结束了
socket.shutdownOutput();//传输完毕信号
//5.确定服务器接收完毕,才能够断开
//6.文件管道流
InputStream inputStream = socket.getInputStream();//byte类型
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while((len2=inputStream.read(buffer2))!=-1){
baos.write(buffer2,0,len2);//0到len2(最后一个)
}
System.out.println(baos.toString());
//7.关闭资源
baos.close();
inputStream.close();
os.close();
fis.close();
socket.close();
}
}
package intIp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerD2 {
public static void main(String[] args) throws Exception {
//1.创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//2.监听客户端的连接
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//3.获取输入流
InputStream is = socket.getInputStream();
//4.文件输出
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
byte[] buffer = new byte[1024];//byte[1024]字节数组
int len;
while((len=is.read(buffer))!=-1){//字节读取判断
fos.write(buffer,0,len);
}
//4.通知客户端,我接收完毕
OutputStream os = socket.getOutputStream();
os.write("接收完毕了,可以断开".getBytes());
//5.关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
3.3 Tomcat服务器(后面细学)
服务端
- 自定义S
- Tomcatu服务器S
客户端
- 自定义C
- 浏览器B
4、UDP(DatagramSocket)
4.1UDP发送消息
没有明确的客户端和服务端界限
package intIp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//不需要连接服务器-不需要建立连接,也不会报错
public class UdpClientD1 {
public static void main(String[] args) throws Exception {
//1.建立一个Socket
DatagramSocket socket = new DatagramSocket();//DatagramSocket数据包,用来发送数据的
//2.建个包
String msg = "你好啊,服务器";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9000;
//3.数据,数据的长度起始,要发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0,msg.getBytes().length,localhost,port);
//DatagramPacket数据库,msg.getBytes()变成字节数组,msg.getBytes().length获得字节的长度,localhost要发送给谁,port端口
//4.发送包
socket.send(packet);
//5.关闭流(包不用关)
socket.close();
}
}
package intIp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//相当于收发快递-还是需要客户端信息(可以相互发送)
public class UdpServerD1 {
public static void main(String[] args) throws Exception {
//开放端口
DatagramSocket socket = new DatagramSocket(9000);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0,buffer.length);
socket.receive(packet);//阻塞接收
System.out.println(packet.getAddress().getHostAddress());//getAddress().getHostAddress()获得包裹从哪里来的
System.out.println(new String(packet.getData(),0,packet.getLength()));//new String转换,packet.getData()获得数据
//关闭连接
socket.close();
}
}
4.2UDP实现聊天(循环发送和循环接收消息)
类似于网上咨询
package intIp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class UdpSenderD1 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据,控制台读取System.in
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//BufferedReader读取为buffer数据
while(true){
String data = reader.readLine();//readLine行读取
byte[] datas = data.getBytes();//String时不可读的,所以要转换为字节
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
//读取内容 和 发送对象
socket.send(packet);
if(data.equals("bye")){
break;
}
}
socket.close();
}
}
package intIp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpReceiveD1 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(6666);//可以接收
while(true){
//准备接收包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
socket.receive(packet);//阻塞式接收包裹
//断开连接 bye
byte[] data = packet.getData();
String receiveData = new String(data,0, packet.getLength());
System.out.println(receiveData);
if(receiveData.equals("bye")){
break;
}
}
socket.close();
}
}
4.3既可以接收方,也可以是发送方(多线程实现)——不想学了,要用再学吧
4.4URL(统一资源定位符)下载网络资源
https://www.baidu.baidu.com -统一资源定位符,定位互联网上的某一个资源
解析
协议://ip地址:端口/项目名/资源 -可以少但不能多
package intIp;
import java.net.MalformedURLException;
import java.net.URL;
public class URLD1 {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://localhost:8080/hellowworld/index.jsp?username"); //URL网络
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()); //参数
}
}
package intIp;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
//下载网上资源
public class URLDown {
public static void main(String[] args) throws Exception {
//1.下载地址
URL url = new URL("\n" +
"https://m801.music.126.net/20240824212951/b36e9f3a1607a43809d520d5d7e25427/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/45222342171/49e2/c967/35b4/ee52dbb917c9594e82fe6d9b3bf27667.m4a");
//2.连接到这个资源 HTTP
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//url.openConnection打开链接HttpURLConnection
InputStream inputStream = urlConnection.getInputStream();//字节输入流
FileOutputStream fos = new FileOutputStream("f.m4a");//文件字节输出流
byte[] buffer = new byte[1024];
int len;
while((len=inputStream.read(buffer))!=-1){
fos.write(buffer,0,len);//写出这个数据
}
fos.close();
inputStream.close();
urlConnection.disconnect();//断开连接
}
}
标签:java,socket,编程,网络,System,process5,new,import,net
From: https://www.cnblogs.com/moulixu/p/18378279