文章目录
网络编程
一、网络编程三要素
1、IP概述
A:IP概述:所谓IP地址就是给每个连接在Internet上的主机分配的一个32bit地址。
B:IP地址的组成
IP地址 = 网络地址+主机地址
A类IP地址:第一段号码为网络地址,剩下的三段号码为本地计算机的号码
B类IP地址:前二段号码为网络地址,剩下的二段号码为本地计算机的号码
C类IP地址:前三段号码为网络地址,剩下的一段号码为本地计算机的号码
C:IP地址分类
A类 1.0.0.1---127.255.255.254
(1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
(2)127.X.X.X是保留地址,用做循环测试用的。
B类 128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。
C类 192.0.0.1---223.255.255.254 192.168.x.X是私有地址
D类 224.0.0.1---239.255.255.254
E类 240.0.0.1---247.255.255.254
D:特殊地址
127.0.0.1 回环地址,可用于测试本机的网络是否有问题. ping 127.0.0.1
DOS命令 ipconfig:查看本机IP地址
xxx.xxx.xxx.255 广播地址
2、端口概述
端口:
物理端口:网卡口
逻辑端口
a:每个网络程序都会有一个逻辑端口
b:用于标识进程的逻辑地址,不同进程的标识不同
c:有效端口:0~65535(两个字节),其中0~1023系统使用或保留端口。
3、协议概述
协议:
UDP
将数据源和目的封装成数据包中,不需要建立连接;
每个数据报的大小在限制在64k;
因无连接,是不可靠协议;
不需要建立连接,速度快
TCP
建立连接,形成传输数据的通道;
在连接中进行大数据量传输;
需要连接所以是可靠协议;
必须建立连接,效率会稍低
二、InetAddress类的使用和Socket通信原理
1、InetAddress类的使用
//获取主机名的DOS命令 :hostname
A:InetAddress类的概述
此类表示互联网协议 (IP) 地址。
B:InetAddress类的常用方法
public static InetAddress getByName(String host)//在给定主机名的情况下确定主机的 IP 地址
public String getHostAddress()//获取IP
public String getHostName()//获取主机名
public static InetAddress getLocalHost()//返回本地主机
import java.net.InetAddress;
import java.net.UnknownHostException;
public class MyTest {
public static void main(String[] args) throws UnknownHostException {
//在给定主机名(或IP)的情况下确定主机的IP地址
InetAddress byName = InetAddress.getByName("192.168.18.101");
System.out.println(byName);// /192.168.18.101
//主机名
System.out.println(byName.getHostName());//LAPTOP-CD98F7A0
//IP
System.out.println(byName.getHostAddress());//192.168.18.101
//本地主机
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);//LAPTOP-CD98F7A0/192.168.18.101
}
}
2、Socket通信原理
Socket=IP+端口号
A:Socket套接字概述:
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
B:Socket原理机制:
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
三、UDP协议
1、UDP协议发送数据
- 步骤:
- a: 创建UDP通讯客户端对象(DatagramSocket)
- b: 创建数据报包 public DatagramPacket(byte[] buf, int length, InetAddress address,int port)
- c: 发送数据
- d: 释放资源
import java.io.IOException;
import java.net.*;
public class UDPClient {
public static void main(String[] args) throws IOException {
//创建UDP通讯客户端对象
DatagramSocket datagramSocket = new DatagramSocket();
byte[] bytes = "你好!".getBytes();
InetAddress byName = InetAddress.getByName("192.168.11.101");
//创建数据报包
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byName, 8888);
//发送数据
datagramSocket.send(datagramPacket);
//释放资源
datagramSocket.close();
}
}
2、UDP协议接收数据
- 步骤:
- a: 创建UDP通讯协议服务器端对象(DatagramSocket),注意要用有参数构造指定端口号
- b: 创建数据报包,用来接收数据 // public DatagramPacket(byte[] buf, int length)
- c: 接收数据 receive(dp) ;
- d: 解析数据报包,拿出数据
dp.getData(); //获取数据的字节数组
dp.getLength();//获取数据的字节长度
- e: 释放资源
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer {
public static void main(String[] args) throws IOException {
//创建UDP通讯协议服务器端对象,并指定端口
DatagramSocket datagramSocket = new DatagramSocket(8888);
byte[] bytes = new byte[1024];
//创建数据报包
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
System.out.println("等待连接...");
//接收数据
datagramSocket.receive(datagramPacket);
//获取数据的字节数组,即上面传入的数组
byte[] data = datagramPacket.getData();
//获取数据的字节长度
int length = datagramPacket.getLength();
String s = new String(data, 0, length);
System.out.println(s);
//释放资源
datagramSocket.close();
}
}
3、使用UDP协议模拟聊天
聊天人:A
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class A {
public static void main(String[] args) throws IOException {
new Thread(){
@Override
public void run() {
DatagramSocket datagramSocket = null;
try {
datagramSocket = new DatagramSocket(8888);
System.out.println("等待连接...");
while (true) {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
int length = datagramPacket.getLength();
String hostName = datagramPacket.getAddress().getHostName();
String s = new String(data, 0, length);
System.out.println(hostName+"B给你发来消息:"+s);
if(s.equals("拜拜")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
datagramSocket.close();
}
}
}.start();
sendAMessage();
}
private static void sendAMessage() throws IOException {
DatagramSocket datagramSocket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送给B的内容:");
String s = scanner.nextLine();
byte[] bytes = s.getBytes();
InetAddress byName = InetAddress.getByName("192.168.18.101");
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byName, 11111);
datagramSocket.send(datagramPacket);
if(s.equals("拜拜")){
break;
}
}
datagramSocket.close();
}
}
聊天人:B
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class B {
public static void main(String[] args) throws IOException {
new Thread(){
@Override
public void run() {
DatagramSocket datagramSocket = null;
try {
datagramSocket = new DatagramSocket(11111);
System.out.println("等待连接...");
while (true) {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
int length = datagramPacket.getLength();
String hostName = datagramPacket.getAddress().getHostName();
String s = new String(data, 0, length);
System.out.println(hostName+"A给你发来消息:"+s);
if(s.equals("拜拜")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
datagramSocket.close();
}
}
}.start();
sendAMessage();
}
private static void sendAMessage() throws IOException {
DatagramSocket datagramSocket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送给A的内容:");
String s = scanner.nextLine();
byte[] bytes = s.getBytes();
InetAddress byName = InetAddress.getByName("192.168.18.101");
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byName, 8888);
datagramSocket.send(datagramPacket);
if(s.equals("拜拜")){
break;
}
}
datagramSocket.close();
}
}
四、TCP协议
1、TCP协议发送数据
* 步骤:
- a: 创建TCP通讯协议客户端对象(Socket)
public Socket(String host, int port)
- b: 获取输出流对象
- c: 写数据
- d: 释放资源
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
//创建TCP通讯协议客户端对象
Socket socket = new Socket("192.168.16.112", 8888);
//获取输出流对象
OutputStream out = socket.getOutputStream();
//写数据
out.write("你好!".getBytes());
//接收服务器端反馈消息
InputStream in = socket.getInputStream();
byte[] bytes = new byte[1024 * 8];
int read = in.read(bytes);
System.out.println(new String(bytes, 0, read));
//释放资源
socket.close();
}
}
2、TCP协议接收数据
* 步骤:
- a: 创建TCP通讯协议服务器端对象(ServerSocket)
- b: 监听客户端
- c: 获取输入流对象
- d: 读取数据
- e: 释放资源
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args)throws IOException {
//创建TCP通讯协议服务器端对象
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("等待连接...");
//监听客户端
Socket accept = serverSocket.accept();
System.out.println("连接成功");
//获取输入流对象
InputStream in = accept.getInputStream();
//读取数据
byte[] bytes = new byte[1024 * 8];
int read = in.read(bytes);
String s = new String(bytes,0,read);
System.out.println(s);
//给客户端反馈消息
OutputStream out = accept.getOutputStream();
out.write("服务器已收到数据".getBytes());
//释放资源
serverSocket.close();
}
}
3、例:多线程开启多个客户端
客户端:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
//创建TCP通讯协议客户端对象
Socket socket = new Socket("192.168.16.112", 9998);
//获取输出流对象
OutputStream out = socket.getOutputStream();
//新建输入流关联上传的文件
FileInputStream in = new FileInputStream("歌曲大联唱2.mp3");
//读写文件
int len=0;
byte[] bytes = new byte[1024];
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
}
//禁用此套接字的输出流
socket.shutdownOutput();
//获取服务端反馈信息
InputStream inputStream = socket.getInputStream();
int len1 = inputStream.read(bytes);
System.out.println(new String(bytes, 0, len1));
//释放资源
socket.close();
in.close();
}
}
服务端:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
//创建TCP通讯协议服务器端对象
ServerSocket ss = new ServerSocket(9998);
System.out.println("等待连接...");
//循环开启线程
int i=0;
while (true){
i++;
//监听客户端
Socket accept = ss.accept();
System.out.println("已成功连接"+i+"个客户端!");
new ServerThread(accept).start();
}
}
}
class ServerThread extends Thread{
Socket accept;
public ServerThread(Socket accept) {
this.accept=accept;
}
@Override
public void run() {
FileOutputStream out=null;
try {
//获取输入流对象
InputStream in = accept.getInputStream();
//新建输出流关联目标文件
out = new FileOutputStream(System.currentTimeMillis()+"歌曲大联唱.mp3");
//读写文件
int len;
byte[] bytes = new byte[1024];
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
}
//获取输出流,给客户端反馈数据
OutputStream out1 = accept.getOutputStream();
out1.write("文件上传成功".getBytes());
}catch (IOException e){
e.printStackTrace();
}finally {
//释放资源
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
五、下载网络资源
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownLoadFile {
public static void main(String[] args) throws IOException {
//URL:统一资源定位符
//协议 IP:端口号 资源路径
String imgUrl = "http://www.westos.org/wp-content/uploads/2017/10/5D5DD3783D9955F5472C0B84F1BD14E5_21.jpg";
URL url = new URL(imgUrl);
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置一些参数
conn.setRequestMethod("GET");//设置请求方式,默认是 GET
conn.setConnectTimeout(3000);//设置请求超时时间
//获取相应状态码
int code = conn.getResponseCode(); //200 代表成功响应
System.out.println(code);//200
String msg = conn.getResponseMessage();//获取响应消息
System.out.println(msg);//OK
int length = conn.getContentLength();//获取网络资源文件的大小
System.out.println(length);//525610
if (code == 200) {
//获取输入流,读取服务器响应 的字节数据
InputStream in = conn.getInputStream();
FileOutputStream out = new FileOutputStream("my.jpg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
out.close();
System.out.println("下载成功");
}
}
}