由点和线组成,表示多个对象之间的相互联系。
多台计算机之间相互联系,通过通信线路连接,作用是实现资源共享和信息传递。
互联网:指计算机之间相互连接,少量连接叫做局域网,俗称内网。
万维网:世界上所有的计算机相互连接的网络。俗称外网。
物联网:万物互联。指将普通的事物也通过手段连入到互联网中。
网络编程实现计算机之间的连接和通信。
应用层:常见的应用,文件管理、远程操作等。(HTTP、FTP、SMTP)
表示层:负责定义和转换数据格式。(如选择二进制或ASCII。)
会话层:建立和维持通话。
传输层:定义传输层一些协议。(TCP、UDP协议)
网络层:定义网络节点的逻辑地址。(IP地址)
链路层:通过协议或规程来控制正确性。(MAC)
物理层:提供传输信号和物理介质(网线、光纤等)
应用层:即OSI模型中的会话层、表示层、应用层。
传输层
网络层
网络接口层:即OSI模型中的物理层和链路层。
TCP:传输控制协议,面向连接的、可靠的、基于字节流的,数据大小无限制。连接时需要3次握手,断开时需要4次挥手(保证可靠性)。
UDP:用户数据报协议,是一种无连接的传输层协议,简单不可靠的服务。每个包的大小不能超过64KB。
是互联网上分配给设备的唯一标识。
分为IPV4和IPV6:
IPV4:是指4个字节,分4段,每段0~255之间,中间使用点号隔开,最大255.255.255.255
IPV6:是指16个字节,分8段,每段0~65535之间,最大FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF
注意:现在是IPV4和IPV6的一个混用的时间节点。
回环地址:127.0.0.1表示本机
查看IP命令:ipconfig
测评IP命令:ping IP地址 -t
是在设备上对程序的唯一标识。
端口号是一个数字,0~65535区间
系统常用端口01023,软件常用端口102310000,意味着写程序时,最好使用10000以后的端口,避免端口冲突。
常用软件的端口:
MySQL:3306
tomcat:8080
Oracle:1521
web服务器默认端口:80
封装IP地址的对象。
public class TestMain {
public static void main(String[] args) throws Exception {
InetAddress addr = InetAddress.getLocalHost(); // 得到本机的信息
System.out.println(addr.getHostName()); // 本机名称
System.out.println(addr.getHostAddress()); // 本机IP
InetAddress addr1 = InetAddress.getByName("LH"); // 通过主机名或者IP地址得到网络上对应设备
System.out.println(addr1.getHostName());
System.out.println(addr1.getHostAddress());
}
}
基于TCP协议的编程。
主要分为客户端的Socket(套接字)以及服务器端的ServerSocket
编程时需要知道IP地址和端口号。
编程步骤:
服务器:
- 创建ServerSocket,指定端口号
- 调用accept方法,等待客户端接入
客户端:
- 创建Socket,指定服务器的IP和端口号,建立连接
- 通过字节流进行输入输出通信
服务端也使用字节流进行输入输出通信。
public class TestServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(6666);
System.out.println("服务器正在等待客户端的接入");
Socket socket = server.accept(); // 等待接收客户端接入
// 读取客户端的内容
InputStream is = socket.getInputStream();
byte [] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.println(str);
}
}
}
public class TestClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("192.168.58.71", 6666); // 建立客户端
System.out.println("客户端建立完成");
OutputStream os = socket.getOutputStream();
String str = "hello, world";
os.write(str.getBytes());
}
}
public class MyServer {
// 定义一个hashmap用来存储所有的客户端
public static ConcurrentHashMap<String, Socket> map = new ConcurrentHashMap<String, Socket>();
public static void main(String[] args) {
try {
// 创建一个服务器
ServerSocket server = new ServerSocket(6666);
System.out.println("服务器创建成功,欢迎您的加入!");
// 无限循环等待接收客户端的连接
while(true) {
Socket socket = server.accept();
// 得到key(IP地址和端口号)
String key = socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
// 将接收到的连接存入集合
map.put(key, socket);
// 每接收一个客户端创建一个线程来处理该客户端的消息
MyServerThread thread = new MyServerThread(socket);
thread.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class MyClient {
public static void main(String[] args) {
try {
// 创建一个客户端
Socket socket = new Socket("192.168.58.71", 6666);
// 创建一个写的线程来处理该客户端的写操作
MyClientWriteThread thread = new MyClientWriteThread(socket);
thread.start();
// 得到客户端的读取信息的流
InputStream is = socket.getInputStream();
// 无限循环读取信息
while(true) {
byte [] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.println(str);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class MyServerThread extends Thread{
private Socket socket;
public MyServerThread(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
String key = socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
System.out.println("欢迎"+key+"加入");
// 得到客户端信息
try {
// 得到客户端输入输出流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 无限循环
while(true) {
// 接收客户端的信息
byte [] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
String msg = new String(buffer, 0, len);
System.out.println(msg);
// 判断该信息是要群发还是单发
String[] arr = msg.split("-");
if(arr != null && arr.length == 2) {
Socket toSocket = MyServer.map.get(arr[0]);
msg = key + "对你说:" + arr[1];
// 单独发送消息
sendTo(toSocket, msg);
}else {
// 群发
sendToAll(key + "说:" + msg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendToAll(String msg) {
for (Socket socket : MyServer.map.values()) {
sendTo(socket, msg);
}
}
public void sendTo(Socket socket, String msg) {
try {
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class MyClientWriteThread extends Thread{
private Socket socket;
public MyClientWriteThread(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
// 得到客户端的输出流
try {
OutputStream os = socket.getOutputStream();
// 定义一个键盘输入
Scanner input = new Scanner(System.in);
// 无限循环,接收控制台输入,将其发送(输出)到服务器
while(true) {
String str = input.nextLine();
os.write(str.getBytes());
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class TestMain1 {
public static void main(String[] args) {
sendMsg("一会去看篮球赛");
}
private static void sendMsg(String msg) {
try {
DatagramSocket ds = new DatagramSocket();
InetAddress ip = InetAddress.getByName("192.168.50.8"); // ip
int port = 2425; // 端口号
// 1:100:飞秋名:主机名:32:信息
String str = "1:100:程灿:LAPTOP-DL0IQI8H:32:" + msg; // 协议和内容
// 打包
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.getBytes().length, ip, port);
ds.send(dp); // 发送消息
} catch (Exception e) {
e.printStackTrace();
}
}
}