1. 概述
- 计算机网络:是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
- 网络编程的目的:传播交流信息、数据交换、通信
- IP:端口 定位到这个计算机上的资源
- javaweb:网页编程 B/S
- 网络编程: TCP/IP C/S
2. 网络通信的要素
-
IP和端口号
-
网络通信协议 tcp、udp
3. IP
-
ip地址:InetAddress
-
唯一定位一台网络上的计算机
-
127.0.0.1 本机localhost
-
ip地址的分类
-
ipv4 / ipv6
- ipv4:例如:127.0.0.1,由4个字节(32位)组成,每个字节长度0-255,大概42亿个
- ipv6:例如:2000:0bb2:1245:0000:0000:1aaa:1212:21cc,128位。8个无符号整数
-
公网(互联网) / 私网(局域网)
-
ABCDE类地址
-
A类IP范围 1.0.0.1 - 126.255.255.254
B类IP范围 128.1.0.1 - 191.254.255.254
C类IP范围 192.0.1.1 - 223.255.254.254
D类IP范围 224.0.0.1 - 239.255.255.254
E类IP范围 240.0.0.0 - 255.255.255.254
-
-
192.168.xxx.xxx,专门给组织内部使用的局域网
-
//测试ip public class TestInetAddress{ public static void main(String[] args){ try{ //查询本机ip地址 InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1"); System.out.println(inetAddress1); InetAddress inetAddress2 = InetAddress.getByName("localhost"); System.out.println(inetAddress2); InetAddress inetAddress3 = InetAddress.getLocalHost(); System.out.println(inetAddress3); //查询网站ip地址 InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com"); System.out.println(inetAddress4); //常用方法 System.out.println(inetAddress4.getAddress()); // [B@7852e922 System.out.println(inetAddress4.getCanonicalHostName()); //规范的地址 14.215.177.38 System.out.println(inetAddress4.getHostAddress()); //ip 14.215.177.38 System.out.println(inetAddress4.getHostName()); //域名 www.baidu.com }catch(UnknownHostException e){ e.printStackTrace(); } } }
-
4. 端口
端口表示计算机上的一个程序的进程
-
不同的进程有不同的端口号,用来区分软件
-
被规定0-65535
-
TCP,UDP:65535*2
-
端口分类
- 公有端口:0-1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
- 程序注册端口:1024-49151,分配用户或者程序
- Tomcat:8080
- MySQL:3306
- Oracle:1521
- 动态、私有:49152-65535(尽量别占用)
- 公有端口:0-1023
-
dos常用命令
netstat -ano #查看所有的端口 netstat -ano|findstr "8080" #查看指定的端口 tasklist|findstr "8080" #查看指定端口的进程
//测试端口 public class TestInetSocketAddress { public static void main(String[] args) { InetSocketAddress address = new InetSocketAddress("127.0.0.1",8080); InetSocketAddress address2 = new InetSocketAddress("localhost",8080); System.out.println(address); // /127.0.0.1:8080 System.out.println(address2); //localhost/127.0.0.1:8080 //常用方法 System.out.println(address.getAddress()); // /127.0.0.1 System.out.println(address.getHostName()); //地址 /127.0.0.1 System.out.println(address.getPort()); //端口 8080 } }
5. 通信协议
-
网络通信协议:速率、传输码率、代码结构、传输控制
-
TCP/IP协议簇:实际上是一组协议
- 重要的协议
- TCP:用户传输协议
- UDP:用户数据报协议
- 出名的协议
- TCP:用户传输协议
- IP:网络互连协议
- 重要的协议
-
TCP、UDP对比
-
TCP:打电话
-
连接、稳定
-
三次握手 四次挥手:至少连接三次才能保持连接
#三次握手 A:你瞅啥? B:瞅你咋的? A:干一场! 连接成功...... #四次挥手 A:我要走了! B:你要走了吗? B:你真的要走了吗? A:我真的要走了! 已断开......
-
客户端、服务端
-
传输完成,释放连接,效率低
-
-
UDP:发短信
- 不连接,不稳定
- 客户端、服务端:没有明确的界限
- 不管有没有准备好,都可以发送出去
-
6. TCP
服务端:
1.建立服务的端口ServerSocket
2.等待用户的连接accept
3.接收用户信息
//服务端
public class TcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.得有一个地址
serverSocket = new ServerSocket(9999);
//2.等待客户端连接
socket = serverSocket.accept();
//3.读取客户端的消息
is = socket.getInputStream();
/*
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer))!=-1){
String msg = new String(buffer,0,len);
System.out.println(msg);
}
*/
//管道流
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
baos.write(buffer,0,len);
}
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 {
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();
}
}
}
}
}
客户端:
1.连接服务器Socket
2.发送消息
//客户端
public class TcpClient {
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;
//2.创建一个socket连接
socket = new Socket(serverIP,port);
//3.发送消息 IO流
os = socket.getOutputStream();
os.write("你好!".getBytes());
} catch (Exception 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();
}
}
}
}
}
TCP实现文件上传
//客户端
public class TcpClient {
public static void main(String[] args) throws Exception{
//创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("D:\\1.jpg"));
//写出文件
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//通知服务器传输完毕
socket.shutdownOutput();
//确定服务器接收完毕,断开连接
InputStream is = socket.getInputStream();
//管道流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while((len2 = is.read(buffer2)) != -1){
baos.write(buffer2,0,len2);
}
System.out.println(baos.toString());
//关闭资源
baos.close();
is.close();
fis.close();
os.close();
socket.close();
}
}
//服务端
public class TcpServer {
public static void main(String[] args) throws Exception{
//创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//监听客户端的连接
Socket socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputStream(new File("D:\\11.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
//接收完毕通知客户端
OutputStream os = socket.getOutputStream();
os.write("已接收完毕,请断开连接!".getBytes());
//关闭资源
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
7. UDP
-
不用连接,需要只要对方的地址
//发送端 //不需要连接服务器 public class UdpClient { public static void main(String[] args) throws Exception { //1.建立一个socket DatagramSocket socket = new DatagramSocket(); //2.建包 String msg = "你好服务器"; //3.发送给谁 InetAddress localhost = InetAddress.getByName("localhost"); int port = 9090; //4.数据,数据长度起始,要发送给谁 DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0 ,msg.getBytes().length, localhost, port); //5.发送包 socket.send(packet); //6.关闭流 socket.close(); } } //接收端 //等待客户端的连接 public class UdpServer { public static void main(String[] args) throws Exception{ //开放端口 DatagramSocket socket = new DatagramSocket(9090); //接收数据包 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length); socket.receive(packet); //阻塞接收 System.out.println(packet.getAddress().getHostAddress()); System.out.println(new String(packet.getData(),0,packet.getLength())); //关闭连接 socket.close(); } }
-
循环发送接收消息
//发送者 public class UdpSender { public static void main(String[] args) throws Exception { //1.建立一个socket DatagramSocket socket = new DatagramSocket(8888); //2.准备数据 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while(true) { String data = reader.readLine(); byte[] datas = data.getBytes(); //3.数据,数据长度起始,要发送给谁 DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666)); //4.发送包 socket.send(packet); if(data.equals("bye")) { break; } } //5.关闭流 socket.close(); } } //接收者 public class UdpReceive { 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); //阻塞式接收 //断开连接 byte[] data = packet.getData(); String receiveData = new String(data,0,data.length); System.out.println(receiveData); if(receiveData.equals("bye")) { break; } } socket.close(); } }
-
实现聊天
发送类
public class TalkSend implements Runnable{ DatagramSocket socket = null; BufferedReader reader = null; private int fromPort; private String toIP; private int toPort; public TalkSend(int fromPort, String toIP, int toPort) { super(); this.fromPort = fromPort; this.toIP = toIP; this.toPort = toPort; try { //建立一个socket socket = new DatagramSocket(fromPort); //准备数据 reader = new BufferedReader(new InputStreamReader(System.in)); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { String data; try { data = reader.readLine(); byte[] datas = data.getBytes(); // 数据,数据长度起始,要发送给谁 DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,new InetSocketAddress(this.toIP, this.toPort)); // 发送包 socket.send(packet); if (data.equals("bye")) { break; } } catch (IOException e) { e.printStackTrace(); } } // 关闭流 socket.close(); } }
接收类
public class TalkReceive implements Runnable { DatagramSocket socket = null; private int port; private String msgFrom; public TalkReceive(int port,String msgFrom) { this.port = port; this.msgFrom = msgFrom; try { // 开放端口 socket = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { try { // 准备接收包裹 byte[] container = new byte[1024]; DatagramPacket packet = new DatagramPacket(container, 0, container.length); socket.receive(packet);// 阻塞式接收 // 断开连接 byte[] data = packet.getData(); String receiveData = new String(data, 0, data.length); System.out.println(msgFrom+":"+receiveData); if (receiveData.equals("bye")) { break; } } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
老师
public class TalkTeacher { public static void main(String[] args) { //开启两个线程 new Thread(new TalkSend(5555, "localhost", 8888)).start(); new Thread(new TalkReceive(9999, "学生")).start(); } }
学生
public class TalkStudent { public static void main(String[] args) { //开启两个线程 new Thread(new TalkSend(7777, "localhost", 9999)).start(); new Thread(new TalkReceive(8888, "老师")).start(); } }
8. URL
-
统一资源定位符:定位互联网上的某一个资源
协议://ip地址:端口号/项目名/资源
public class Url { public static void main(String[] args) throws MalformedURLException { URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=aaa&password=123"); 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()); //参数 } }
-
URL下载网络资源
public class UrlDown { public static void main(String[] args) throws Exception { //下载地址 URL url = new URL("http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"); //连接到这个资源 HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream is = urlConnection.getInputStream(); FileOutputStream fos = new FileOutputStream("D:\\baidu.jpg"); byte[] buffer = new byte[1024]; int len; while((len = is.read(buffer)) != -1) { fos.write(buffer,0,len); //写出数据 } fos.close(); is.close(); urlConnection.disconnect(); //断开连接 } }