文章目录
网络编程
计算机网络
-
互联网:(Internet)点与点向相连
-
万维网(WWW-World Wide Web)端与端相连
-
物联网:(IoT -Internet of things)物与物相连
-
网络编程:让计算机与计算机之间建立连接,进行通信。
-
网络分类
1.局域网
2.城域网
3.广域网
网络模型
- OSI(Open System Interconnection)开放式系统互联
TCP/IP模型
- 一组用于实现网络互联的通信协议,将协议分为四个层次
TCP/UDP
- TCP协议:Transmission Control Protocol传输控制协议
- 是一种面向连接的,可靠的,基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
- UDP协议:User Datagram Protocol用户数据报协议
- 是一种无连接的传输层协议,提供面向事物的简单不可靠信息传送服务,每个包的大小是64kb.
IP
- IP协议:Internet Protocol Address 互联网协议地址/网络协议地址
- 分配给互联网设备的数字标签(唯一标识)。
- IP地址分为两种;
- IPV4:4字节32位整数,并分成4段8位的二进制,每8位之间用圆点隔开,每8位整数可以转换为一个0-255的十进制整数。
- 格式D.D.D.D 例如:127.0.0.1
- IPV6:16字节128位整数,并分成8段十六进制数,每16位之间用圆点隔开。每16位整数可以转化为一个0-655355的十进制整数。冒号分十六进制
- 格式:X:X:X:X:X:X:X:X
- IPV4:4字节32位整数,并分成4段8位的二进制,每8位之间用圆点隔开,每8位整数可以转换为一个0-255的十进制整数。
IPV4的应用分类
- A类:政府机构,1.0.0.1-126.255.255.254
- B类:中型企业,128.0.0.1-191.255.255.254
- C类:个人用户,192.0.0.1-223.255.255.254
- D类:用于组播,224.0.0.1-239.255.255.254
- E类:用于实验,240.0.0.1-255.255.255.254
- 回环地址:127.0.0.1,指本机,一般用于测试使用
- 查看IP命令:ipconfig
- 测试IP命令:ping D.D.D.D
Port
- 端口号:在通信实体上进行网络通讯的程序的唯一标识,16位
- 一个程序可以占用多个端口
- 端口分类:
- 公认端口:0-1023
- 注册端口:1024-49151
- 动态或私有端口:29152-65535
- 常用端口:
- Mysql:3306
- Oracle:1521
- Tomcat:8080
- SMTP:25
- Web服务器:80
- FTP服务器:21
- HTTPS 443
InetAddress类
-
概念:表示互联网协议(IP)地址对象,封装了与该IP地址相关的所有信息,并提供获取信息的常用方法。
-
方法:
- public static InetAddress getLocalHost()获取本地主机地址对象。
- public static InetAddress getByName(String host)根据主机名称获得地址对象
- public static InetAddress[]getAllByName(String host)获得所有相关地址对象
- public String getHostAddress()获取IP地址字符串
- public String getHostName()获得IP地址主机名
- public Boolean isReachable(int timeout):测试地址是否可达
-
InetAddress类的使用
-
1.本机地址
-
2.局域网地址
-
3.外网地址
//1.本机地址
InetAddress inetAddress = InetAddress.getLocalHost();
System.out.println("IP地址:" + inetAddress.getHostAddress() + " 主机名" + inetAddress.getHostName());
InetAddress inetAddress1 = InetAddress.getByName("169.254.56.36");
System.out.println("IP地址:" + inetAddress1.getHostAddress() + " 主机名" + inetAddress1.getHostName());
InetAddress inetAddress2 = InetAddress.getByName("127.0.0.1");
System.out.println("IP地址:" + inetAddress2.getHostAddress() + " 主机名" + inetAddress2.getHostName());
//2.局域网
InetAddress inetAddress3 = InetAddress.getByName("10.0.139.165");
System.out.println("IP地址:" + inetAddress3.getHostAddress() + " 主机名" + inetAddress3.getHostName());
System.out.println("3秒是否可达?"+inetAddress3.isReachable(3000));
//3.外网地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
System.out.println("3秒是否可达?"+inetAddress4.isReachable(3000));
System.out.println("IP地址:" + inetAddress4.getHostAddress() + " 主机名" + inetAddress4.getHostName());
InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com");
for (InetAddress inetAddress : allByName) {
System.out.println(inetAddress.getHostAddress());
}
基于TCP的网络边恒
-
Socket编程:
- Socket(套接字)是网络中的一个通信节点。
- 分为客户端Socket与服务器ServerSocket.
- 通信要求:IP地址+端口号
-
开发步骤
- 1.建立通信连接(回话):
- 创建ServerSocket,指定端口号。
- 调用accept等待客户端接入
- 2.客户端请求服务器:
- 创建Socket,指定服务器IP+端口号
- 使用输出流,发送请求数据给服务器
- 使用输入流,接受响应数据到客户端(等待)
- 3.服务器响应客户端:
- 使用输入流,接受请求数据到服务器(等待)
- 使用输出流,发送响应数据给客户端
客户端给服务端发信息
//Server.java /** * 基于TCP协议的服务器端 * 步骤: * 1.创建服务器套接字,并绑定端口号 * 2.侦听客户端连接,返回socket * 3.获取输入,输出流 * 4.处理数据 * 5.关闭资源 */ public class TcpServer { public static void main(String[] args) throws IOException { // * 1.创建服务器套接字,并绑定端口号 ServerSocket listener = new ServerSocket(8080); // * 2.侦听客户端连接,返回socket,阻塞方法,直到客户端连接 Socket socket = listener.accept(); System.out.println("Server start."); // * 3.获取输入,输出流 InputStream inputStream = socket.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // * 4.处理数据 String info = bufferedReader.readLine(); System.out.println("Client>>>>" + info); // * 5.关闭资源 listener.close(); bufferedReader.close(); } }
- 1.建立通信连接(回话):
//Client.java
/**
* 基于TCP协议的服务器
* 四个步骤
* 1.创建一个客户端套接字socket,并指定服务器的地址和端口号
* 2.获取输入,输出流
* 3.处理数据
* 4.关闭资源
*/
public class TcpClient {
public static void main(String[] args) throws IOException {
// * 1.创建一个客户端套接字socket,并指定服务器的地址和端口号
Socket socket = new Socket("169.254.56.38",8080);
// * 2.获取输入,输出流
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,"utf-8"));
// * 3.处理数据
bufferedWriter.write("好久不见");
// * 4.关闭资源
bufferedWriter.close();
socket.close();
}
}
加强版
package com.demodong.java.test04;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
/**
* author:demodong
* 2020/8/10
* 15:02
*/
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 8080);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
int port = socket.getPort();
InetAddress server = socket.getInetAddress();
String name = server.getHostName();
String address = server.getHostAddress();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("Client");
bufferedWriter.write(scanner.nextLine());
bufferedWriter.newLine();
bufferedWriter.flush();
String message = bufferedReader.readLine();
System.out.println(address + name + port + ":" + message);
}
}
}
package com.demodong.java.test04;
import com.sun.org.apache.bcel.internal.generic.NEW;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* author:demodong
* 2020/8/10
* 14:57
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket listener = new ServerSocket(8080);
Socket socket = listener.accept();
BufferedReader bufferedReader= new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF8"));
BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF8"));
InetAddress client = socket.getInetAddress();
byte[] address = client.getAddress();
String name = client.getHostName();
int port = socket.getPort();
Scanner scanner=new Scanner(System.in);
while (true){
String message = bufferedReader.readLine();
System.out.println(address+name+":"+port+message);
System.out.print("Server:");
bufferedWriter.write(scanner.nextLine());
bufferedWriter.newLine();
bufferedWriter.flush();
}
}
}
文件
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket listener = new ServerSocket(8080);
Socket socket = listener.accept();
InputStream inputStream = socket.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("d:\\desktop\\demo_copy.txt");
byte[] buffers = new byte[1024];
int len = 0;
while (true) {
while ((len = inputStream.read(buffers)) != -1) {
fileOutputStream.write(buffers, 0, len);
}
fileOutputStream.close();
}
}
}
package com.demodong.java.test06;
import com.sun.org.apache.bcel.internal.generic.NEW;
import java.io.*;
import java.net.Socket;
/**
* author:demodong
* 2020/8/10
* 15:29
*/
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("d:\\desktop\\demo.txt"));
byte[] buffers = new byte[1024];
int len = 0;
while ((len = bufferedInputStream.read(buffers)) != -1) {
outputStream.write(buffers, 0, len);
}
bufferedInputStream.close();
}
}
多线程服务器
//ChatRunnable.java
public class ChatRunnable implements Runnable {
private Socket socket;
public ChatRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
InputStream inputStream = null;
try {
inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String s = bufferedReader.readLine();
System.out.println(s);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
bufferedWriter.write("我收到了" + s);
bufferedWriter.newLine();
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Client.java
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 8080);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
bufferedWriter.write("nihaoya");
bufferedWriter.newLine();
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String message = bufferedReader.readLine();
System.out.println(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
//ChatServer.java
public class ChatServer {
public static void main(String[] args) throws IOException {
ExecutorService executorService = Executors.newCachedThreadPool();
ServerSocket listener=new ServerSocket(8080);
Socket socket = null;
while (true){
socket=listener.accept();
executorService.submit(new ChatRunnable(socket));
}
}
}
UDP(Usr Datagram Protocol)
- UPD特点:
- 无连接,不可靠,每个数据包大小64k
- 速度快,可实现广播发送
- DatagramSocket:表示用来发送和接受数据包的套接字
- DatagramPacket:表示数据包
UPD简单案例
//Sender.java
public class Sender {
public static void main(String[] args) throws Exception {
/**
*
* UDP协议的发送方
*/
//1.创建DatagramSokcet,可以不提供端口号,自动分配一个端口号。
DatagramSocket datagramSocket = new DatagramSocket();
//2.创建DatagramPacket,发送数据报
byte[] data = "好久不见".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), 9090);
//3.发送
datagramSocket.send(datagramPacket);
//4.关闭
datagramSocket.close();
}
}
//Receiver.java
public class Receiver {
public static void main(String[] args) throws Exception {
//1.创建DatagramSocket,指定端口
DatagramSocket datagramSocket = new DatagramSocket(9090);
//2.创建DatagramPacket,接受数据报包
byte[] buf = new byte[1024 * 4];
DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
//3.接受 ,阻塞方法,接收到数据才返回。
System.out.println("hava alreay to receive");
datagramSocket.receive(datagramPacket);
//4.处理数据
String data = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
System.out.println(data);
//5.关闭
datagramSocket.close();
}
}
UDP简单实现聊天
//ChatReciever.java
public class ChatReciever {
public static void main(String[] args) throws Exception {
//1.创建DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket(9090);
//2.创建数据报包
byte[] buffers = new byte[1024 * 10];
DatagramPacket datagramPacket = new DatagramPacket(buffers, buffers.length);
//3.接受
while (true) {
datagramSocket.receive(datagramPacket);
//4.处理数据
String data = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
System.out.println(data);
}
//5.关闭
}
}
//ChatSender.java
public class ChatSender {
public static void main(String[] args) throws Exception {
//1.创建DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket();
//2.创建发送数据报
Scanner scanner = new Scanner(System.in);
while (true) {
String data = scanner.next();
DatagramPacket datagramPacket = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getByName("127.0.0.1"), 9090);
datagramSocket.send(datagramPacket);
if (data.equals("886")) {
datagramSocket.close();
}
}
}
}
可多次发送信息聊天
//ChatReciever.java
public class ChatReciever {
public static void main(String[] args) throws Exception {
//1.创建DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket(8899);
//2.创建数据报包
byte[] buffers = new byte[1024 * 10];
DatagramPacket datagramPacket = new DatagramPacket(buffers, buffers.length);
//3.接受
while (true) {
datagramSocket.receive(datagramPacket);
//4.处理数据
String data = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
System.out.println(datagramPacket.getAddress());
System.out.println(data);
}
//5.关闭
}
}
//ChatSender.java
public class ChatSender {
public static void main(String[] args) throws Exception {
//1.创建DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket();
//2.创建发送数据报
Scanner scanner = new Scanner(System.in);
while (true) {
String data = scanner.next();
DatagramPacket datagramPacket = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getByName("10.0.139.255"),8899);
datagramSocket.send(datagramPacket);
if (data.equals("886")) {
datagramSocket.close();
}
}
}
}
课堂作业
//Client.java
package com.qf.gp2002_4;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/*
* wgy
* 2020/8/10
* 17:26
*/
public class Client {
public static void main(String[] args) {
System.out.println("------------1注册 2登录--------------");
System.out.println("请选择");
Scanner input=new Scanner(System.in);
int choice=input.nextInt();
try {
switch (choice){
case 1:
regist();
break;
case 2:
break;
default:
System.out.println("输入有误");
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void regist() throws Exception{
User user = getInfo();
//1 创建Scoket
Socket socket=new Socket("10.0.139.49", 6666);
//2 获取输入输出流
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
// BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//3 处理数据
//3.1写入
// System.out.println(user.toString());
// bw.write(user.toString());
// bw.newLine();
// bw.flush();
//使用对象流
ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(user);
oos.flush();
//3.2读取
String s = br.readLine();
System.out.println("服务器回复:"+s);
//4 关闭
oos.close();
br.close();
socket.close();
}
//id : ”1001”, name :“tom”, pwd : ”123”, age : 20 , score : 98.5
public static User getInfo(){
Scanner input=new Scanner(System.in);
System.out.println("请输入用户id");
int id=input.nextInt();
System.out.println("请输入姓名");
String name=input.next();
System.out.println("请输入密码");
String pwd=input.next();
System.out.println("请输入年龄");
int age=input.nextInt();
System.out.println("请输入成绩");
double score=input.nextDouble();
User user=new User(id, name, pwd,age,score);
return user;
}
public static void login(){
}
}
//LoginServer.java
package com.qf.gp2002_4;
/*
* wgy
* 2020/8/10
* 17:13
*/
public class LoginServer implements Runnable {
@Override
public void run() {
//实现登录
}
}
//RegisteSery.java
package com.qf.gp2002_4;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
/*
* wgy
* 2020/8/10
* 17:13
*/
public class RegistServer implements Runnable {
@Override
public void run() {
//注册功能
try {
//(1)创建ServerSocket,并指定端口号
ServerSocket listener=new ServerSocket(6666);
System.out.println("注册服务器已启动...");
//(2)侦听,返回socket
Socket socket = listener.accept();
//(3)获取输入输出流
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//(4)处理数据
String data = br.readLine();
//1001 = {id : 1001, name :tom, pwd : 123, age : 20 , score : 98.5}
//4.1获取id
String[] arr = data.split("=");
String id=arr[0];
//4.2读取Properties
File file=new File("users.properties");
//判断文件是否存在
Properties properties=new Properties();
if(file.exists()) {
FileInputStream fis=new FileInputStream(file);
properties.load(fis);
fis.close();
}
//4.3判断id是否存在
if(properties.containsKey(id)){
bw.write(id+"已经存在,请重新注册");
}else{
//注册成功
properties.setProperty(id, arr[1]);
//保存
FileOutputStream fos=new FileOutputStream(file);
properties.store(fos,"用户信息");
fos.close();
bw.write("注册成功");
}
bw.newLine();
bw.flush();
//5关闭资源
br.close();
bw.close();
socket.close();
listener.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//RegistServer2.java
package com.qf.gp2002_4;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
/*
* wgy
* 2020/8/10
* 17:13
*/
public class RegistServer2 implements Runnable {
@Override
public void run() {
//注册功能
try {
//(1)创建ServerSocket,并指定端口号
ServerSocket listener=new ServerSocket(6666);
System.out.println("注册服务器已启动...");
//(2)侦听,返回socket
Socket socket = listener.accept();
//(3)获取输入输出流
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//(4)处理数据
User user = (User) ois.readObject();
//4.2读取Properties
File file=new File("users.properties");
//判断文件是否存在
Properties properties=new Properties();
if(file.exists()) {
FileInputStream fis=new FileInputStream(file);
properties.load(fis);
fis.close();
}
//4.3判断id是否存在
if(properties.containsKey(user.getId())){
bw.write(user.getId()+"已经存在,请重新注册");
}else{
//注册成功
properties.setProperty(user.getId()+"", user.toString().split("=")[1]);
//保存
FileOutputStream fos=new FileOutputStream(file);
properties.store(fos,"用户信息");
fos.close();
bw.write("注册成功");
}
bw.newLine();
bw.flush();
//5关闭资源
ois.close();
bw.close();
socket.close();
listener.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//Server.java
package com.qf.gp2002_4;
/*
* wgy
* 2020/8/10
* 17:14
*/
public class Server {
public static void main(String[] args) {
new Thread(new RegistServer2()).start();
new Thread(new LoginServer()).start();
}
}
//User.java
package com.qf.gp2002_4;
import java.io.Serializable;
/*
* wgy
* 2020/8/10
* 17:31
*/
public class User implements Serializable {
private int id;
private String name;
private String pwd;
private int age;
private double score;
public User(int id, String name, String pwd, int age, double score) {
this.id = id;
this.name = name;
this.pwd = pwd;
this.age = age;
this.score = score;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return this.id+"={" +
"id:" + id +
", name:'" + name + '\'' +
", pwd:'" + pwd + '\'' +
", age:" + age +
", score:" + score +
'}';
}
}