目录
一、什么是计算机网络
1.计算机网络:
将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
2.网络编程的目的: 传播交流信息、数据交换、通信
二、网络通信的两个要素
1. 如何实现网络的通信?
获取通信双方地址:
ip(是唯一的)、端口号
ip+端口 就能定位到具体计算机的某一个具体的应用
规则:网络通信的协议(http,ftp.....)
2. 网络编程中的要素:
IP和端口号、网络通信协议(UDP、TCP)
三、IP地址
1.ip地址(InetAddress)
①唯一定位一台网络上的计算机
②127.0.0.1:本机localhost (如图下面所示,相当于自己给自己呼叫,没有网也可以呼叫成功)
2.IP地址的分类:
ipv4/ipv6:
ipv4: 127.0.0.1 四个字节组成(每个字节0到255),已经用尽了
ipv6:2001:0bb2:aaaa:0015:0000:0000:1aaa:1312 , 128位,8个无符号整数
3.公网私网分类:
公网(互联网)、私网(局域网)
4.关于IP的代码:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IP01 {
public static void main(String[] args) {
try {
//"127.0.0.1" 本机IP地址 (和ping,命令一样)
// InetAddress不能new出来,没有构造器,只能用静态方法返回回来(因为这些静态方法的返回对象就是InetAddress类型的
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
InetAddress inetAddress2 = InetAddress.getByName("localhost");
InetAddress inetAddress3 = InetAddress.getLocalHost();
System.out.println(inetAddress1);
System.out.println(inetAddress2);
System.out.println(inetAddress3);
// 查询网站ip地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress4);
// 常用方法 以百度为例
System.out.println(inetAddress4.getAddress());
System.out.println(inetAddress4.getCanonicalHostName());//规范的名字
System.out.println(inetAddress4.getHostAddress());//ip
System.out.println(inetAddress4.getHostName());//域名 或者 自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
四、端口Port
端口表示计算机上的一个进程(每一户楼是一个ip,那每一户人家就是一个端口,有了ip和端口就能进入到某个人的家里,电脑上的资源就相当于家里的小物件)(也可以理解为,IP是一个电脑,端口是电脑上的软件)
不同的进程有不同的端口号,端口号不能重复(前提是单个协议),目的是用来区分软件(如果在tcp中使用了80端口,但是在udp中也可以使用80端口,并不冲突。
1.端口的分类
公有端口:0-1023 尽量不要使用
HTTP:80
HTTPS:43
FTP:21
TELENT:23
程序注册端口:1014—49151 分配给用户或者程序
Tomacat:8080
MySQL:3306
Oracle:1521
动态、私有端口:49152-65535
任务管理器命令:
netstat -ano 查看所有端口
netstat -ano findstr "5900" 查看 5900端口
tasklist|findstr "8696" 查看指定端口的进程
2.代码
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class SocketAddress {
public static void main(String[] args) {
// 第二个参数是 端口
InetSocketAddress inetSocketAddress01 = new
InetSocketAddress("127.0.0.1",8080);
System.out.println(inetSocketAddress01);
InetSocketAddress inetSocketAddress02 = new
InetSocketAddress("localhost",8080);
System.out.println(inetSocketAddress02);
// 通过Socket获取 InetAddress
InetAddress inetAddress = inetSocketAddress01.getAddress();
System.out.println(inetAddress); //ip地址
System.out.println(inetSocketAddress01.getHostName()); //地址
System.out.println(inetSocketAddress02.getPort()); //端口号
}
}
五、通信协议
协议: 约定,比如说约定好说普通话,而不是方言
网络通信协议:速率、传输码率,代码结构,传输控制....
TCP/IP协议簇:(TCP/IP协议实际上是一组协议)
(首先说明,TCP、IP都是在传输层)
TCP:用户传输协议
IP:网络互联协议
UDP:用户数据报协议(发短信或写邮件,但是不一定到)
TCP与UDP对比:
TCP:打电话
连接、稳定
三次握手、四次挥手
客户端、服务端
传输完成就会释放连接,效率低
UDP:发短信
不连接、不稳定
客户端、服务端,但是没有明确的界限
不管有没有准备好,都可以发给你
代码:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
//客户端
public class TCPClientDemo01 {
public static void main(String[] args) {
// 提升一下作用域
Socket socket = null;
OutputStream os =null;
try {
// 1.客户端要连接服务器,要知道服务器的地址
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
int port = 9999; //这个端口“9999” 是在服务端定义的
// 2.创建一个socket连接
socket = new Socket(serverIP,port);
// 3.发送消息 (使用IO流)
// OutputStream是字节输出流,是抽象的
os = socket.getOutputStream();
os.write("你好,欢迎学习!".getBytes()); //"你好,欢迎学习!".getBytes() 将字符串数组转化为字节数组
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(os !=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
if(socket !=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//不做通信工程底层代码,此代码用的并不多,但是掌握以下思维
//启动的时候,先启动服务器端
//服务器 server
public class TCPServerDeomo01 {
public static void main(String[] args) {
// 放到这里的目的单纯就是为了提升一下作用于,好在finally中对流进行关闭
ServerSocket serverSocket =null;
Socket socket =null;
InputStream is =null;
ByteArrayOutputStream baos =null;
try {
// 1.客户端要连接服务器,要知道服务器的地址,故我们要在服务器这里new一个地址
// 我们需要开启服务端的插槽,需要传一个参数port
// 如此以来我们的服务器地址就是 localhost 9999
serverSocket = new ServerSocket(9999); //Socket是插座的意思
while(true){ //这个死循环就相当于不停的进行监听客户端发过来的消息
// 2. 等待客户端连接过来
// 这个Socket 就是客户端连过来的Socket,只是在不一个类里面
// 相当于通过accept()方法可以获取Socket对象,再获取InputStream就可以获取发送过来的信息了
// 这个Socket相当于这边拿过来,那边拿过去
socket = serverSocket.accept();
// 3.读取客户端的消息(在此利用IO流)
is = socket.getInputStream();
// 管道流
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024]; //用字节数组,减少了内存和硬盘反应,提高运行速率
int readCount = 0;
while(( readCount= is.read(bytes)) !=-1){ //当readCount=-1的时候,就相当于读完了
baos.write(bytes,0,readCount); //第二个参数相当于起始位置,第三个参数相当于末位置
// 但是现在读完还是字节
}
System.out.println(baos.toString());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// 关闭流(先开后关)
if(baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( is!=null){
try {
if(is!=null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}