首先理清一个概念:网络编程不等于网站编程,网络编程即使用套接字来达到进程间通信,现在一般称为TCP/IP编程。
计算机网络:
把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大,功能强的网络系统,从而使众多的计算机可以方便的互相传递信息,共享硬件,软件,数据信息等资源。
计算机网络的主要功能:
计算机网络三高问题: 高并发,高性能,高可用。
计算机网络分类:
(Local Area Network;LAN) 通常我们常见的“LAN”就是指局域网,这是我们最常见、应用最广的一种网络
网络通信协议:
计算机网络中实现通信必须有一些约定,即通信协议;包括对速率,传输代码,代码结构,传输控制步骤,出错控制等制定的标准。
网络通信接口:
为了使两个节点之间能进行对话,必须在他们之间建立通信工具(即接口),使彼此之间,能进行信息交换。接口包括两部分:
为什么要分层:
由于结点之间联系很复杂,在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式就是层次方式,及同层间可以通信,上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。
通信协议的分层规定:
把用户应用程序作为最高层,把物理通信线路作为最底层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。
每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了。
IP地址是用一个点来分成四段的,在计算机内部IP地址是用四个字节来表示的,一个字节代表一段,每一个字节代表的数最大只能到达255。
说到IP地址,就要引入一个类:InetAddress
此类表示互联网协议 (IP) 地址。
InetAddress类无构造方法
常用方法摘要
byte[] getAddress()
返回此 InetAddress 对象的原始 IP 地址。
static InetAddress getByName(String host)
在给定主机名的情况下确定主机的 IP 地址。
String getHostAddress()
返回 IP 地址字符串(以文本表现形式)。
String getHostName()
获取此 IP 地址的主机名。
static InetAddress getLocalHost()
返回本地主机。
127.0.0.1:本机地址,主要用于测试。别名:Localhost
案例
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestIP {
public static void main(String[] args) throws UnknownHostException {
//InetAdress类表示IP地址
//获取本机IP
InetAddress ip = InetAddress.getLocalHost();
System.out.println(ip);
//获得主机名
System.out.println(ip.getHostName());
//获得IP地址
System.out.println(ip.getHostAddress());
}
}
案例二
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestIP2 {
public static void main(String[] args) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
// 获取此 IP 地址的主机名。
System.out.println(inetAddress.getHostName());
//返回 IP 地址字符串(以文本表现形式)。
System.out.println(inetAddress.getHostAddress());
}
}
MySQL(3306),Oracle(1521),Tomcat(8080)等等程序都有自己的端口
查看端口
说到端口,则要引入一个类:InetSocketAddress
此类实现 IP 套接字地址(IP 地址 + 端口号)。
构造方法摘要
InetSocketAddress(InetAddress addr, int port)
根据 IP 地址和端口号创建套接字地址。
InetSocketAddress(int port)
创建套接字地址,其中 IP 地址为通配符地址,端口号为指定值。
InetSocketAddress(String hostname, int port)
根据主机名和端口号创建套接字地址。
常用方法摘要
InetAddress getAddress()
获取 InetAddress。
String getHostName()
获取 hostname。
int getPort()
获取端口号。
案例
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class TestPort {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8082);
System.out.println(inetSocketAddress.getHostName());
//获得InetSocketAddress的端口
System.out.println(inetSocketAddress.getPort());
System.out.println(inetSocketAddress.getHostString());
//返回一个InetAddress对象(IP对象)
InetAddress address = inetSocketAddress.getAddress();
}
}
URI=URL+URN
URI:Uniform Resource Identifier ,统一资源标志符。
URL:Uniform Resource Locator,统一资源定位符。
URN:Uniform Resource Name,统一资源命名。
网络三大基石:HTML,HTTP,URL
构造方法摘要
URL(String spec)
根据 String 表示形式创建 URL 对象。
URL(String protocol, String host, int port, String file)
根据指定 protocol、host、port 号和 file 创建 URL 对象。
URL(String protocol, String host, String file)
根据指定的 protocol 名称、host 名称和 file 名称创建 URL。
常用方法摘要
String getAuthority()
获取此 URL 的授权部分。
int getDefaultPort()
获取与此 URL 关联协议的默认端口号。
String getFile()
获取此 URL 的文件名。
String getHost()
获取此 URL 的主机名(如果适用)。
String getPath()
获取此 URL 的路径部分。
int getPort()
获取此 URL 的端口号。
String getUserInfo()
获取此 URL 的 userInfo 部分。
案例
import java.net.MalformedURLException;
import java.net.URL;
public class TestURL {
public static void main(String[] args) throws MalformedURLException {
URL url2 = new URL("https://www.bilibili.com/");
//获取此的授权部分 URL 。
System.out.println(url2.getAuthority());
//获取此 URL的文件名。
System.out.println(url2.getFile());
//获取端口
System.out.println(url2.getPort());
//获取主机
System.out.println(url2.getHost());
//获得默认端口
System.out.println(url2.getDefaultPort());
//获得路径
System.out.println(url2.getPath());
//获取该 URL的userInfo部分。
System.out.println(url2.getUserInfo());
}
}
需求:完成在线咨询功能,学生和老师在线一对一交流
分析:
UDP基本概念:
实现
接收方
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class PeopleOne {
public static void main(String[] args) throws IOException {
//1.开放一个端口
DatagramSocket socket = new DatagramSocket(5051);
//2.准备容器接收
byte[] receiveBuf = new byte[100];
//3.等待包裹容器封包
DatagramPacket packet = new DatagramPacket(receiveBuf,receiveBuf.length);
System.out.println("等你包裹来。。。。");
while (true){
//4.接收包裹
socket.receive(packet);
//5.解析包裹
String receStr = new String(packet.getData(),0,packet.getLength());
System.out.println("我收到了:"+receStr);
if (receStr.equals("exit")){
break;
}
}
//6.释放资源
socket.close();
}
}
发送方
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class PeopleTwo {
public static void main(String[] args) throws IOException {
//1.指定一个端口进行发送
DatagramSocket socket = new DatagramSocket();
//2.指定一个IP
InetAddress addr = InetAddress.getByName("127.0.0.1");
int port = 5051;
//3.准备一个小容器
byte[] sendBuf;
while (true){
Scanner scanner = new Scanner(System.in);
System.out.println("你要发什么东西:");
String s = scanner.nextLine();
//4.加入要放的数据
sendBuf = s.getBytes();
//5.数据打包
DatagramPacket packet = new DatagramPacket(sendBuf,sendBuf.length,addr,port);
//6.发送包
socket.send(packet);
if (s.equals("exit")){
break;
}
}
//7.释放资源
socket.close();
}
}
需求:完成网络登录功能
分析:
实现
服务器
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) throws IOException {
//服务器开启了一个监听端口
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("开启了服务器");
while (true){
//等待客户端连接
Socket accept = serverSocket.accept();
System.out.println("有一个人连接过来了");
//获得客户端输入的东西
InputStream inputStream = accept.getInputStream();
//包装成DataInputStream流
DataInputStream dataInputStream = new DataInputStream(inputStream);
//通过流流读取消息
String s = dataInputStream.readUTF();
System.out.println(s);
}
}
}
客户端
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class TestClient {
public static void main(String[] args) throws IOException {
//创建同一连接
Socket s = new Socket("127.0.0.1",6666);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF("hello,world!");
}
}
一般的网络编程都称为Socket编程,Socket的英文意思是“插座”。
两台电脑都安装上一个插座,然后使用一根线的两端插到两台电脑的插座上,这样两台电脑就建立好了连接。这个插座就是Socket。
因为互相之间都能互相通信,我说你是我的Server只是从逻辑意义上来讲,我应该把东西先发到你那里去,然后由你来处理,转发。所以你叫Server。但从技术意义上来讲,只有TCP才会分Server和Client。对于UDP来说,从严格意义上来讲,并没有所谓的Server和Client。TCP的Server的插座就叫ServerSocket,Client的插座就叫Socket。
两台计算机互相连接,那么首先必须得知道它们的IP地址,但是只提供IP地址是不够的,还必须要有连接的端口号,也就是要连接到哪个应用程序上。
端口号是用来区分一台机器上不同的应用程序的。端口号在计算机内部是占2个字节。一台机器上最多有65536个端口号。一个应用程序可以占用多个端口号。端口号如果被一个应用程序占用了,那么其他的应用程序就无法再使用这个端口号了。记住一点,我们编写的程序要占用端口号的话占用1024以上的端口号,1024以下的端口号不要去占用,因为系统有可能会随时征用。端口号本身又分为TCP端口和UDP端口,TCP的8888端口和UDP的8888端口是完全不同的两个端口。TCP端口和UDP端口都有65536个。