1.1、概述
计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的:
无线电台...传播交流信息、数据交换、通信
想要达到这个效果需要做什么:
1.需要IP地址、端口,定位到计算机上的某个资源
2.找到主机后如何传输数据?
javaweb:网页编程 B/S
网络编程:TCP/IP C/S
1.2、网络通信的概述
如何实现网络的通信:
1.通信双方的地址:
- ip
- 端口
2.通信协议
小结:
1.网络编程中两个关键的点:
- 如何准确的定位到网络上的一台或多台主机
- 找到主机后如何通信
2.网络编程中的要素:
- ip和端口
- 网络通信协议
1.3、IP
ip地址:InetAddress
- 唯一定位一台网络上的计算机
- ip地址的分类:
- IPV4/IPV6 IPV4:由四个字节组成,0-255 。IPV6:128位。8个无符号的整数
- 公网-私网:192..168.xx.xx 专门给组织机构使用 ABCD类地址
- 域名:记忆IP问题
// 测试ip
public class TestInetAddress {
public static void main(String[] args) {
try {
// 查询本机
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);
// 查询网络地址
InetAddress inetaddress4 = InetAddress.getByName("www.baidu.com");
System.out.println(inetaddress4);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
1.4、端口
端口表示计算机上的一个程序的进程
- 不同的进程有不同的端口号---用来区分软件
- 被规定的范围0-65535
- TCP、UDP:65535*2
- 端口分类:
- 公有端口0-1023
- HTTP:80端口
- HTTPS:443
- FTP:21
- 程序端口:1024-49151,分配用户或程序
- tomcat:8080
- mysql:3306
- Orcale:1521
- 动态、私有 :49152-65535
- 公有端口0-1023
public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
System.out.println(socketAddress);
System.out.println(socketAddress.getAddress());
System.out.println(socketAddress.getHostName());
System.out.println(socketAddress.getPort());
}
}
1.5、通信协议
协议:一种特有的约定。
网络通信协议:速率、传输码率、代码结构、传输控制....
TCP/IP协议簇:实际上是一组协议
TCP:用户传输协议
UDP:用户数据报协议
TCP UDP对比
TCP:打电话
- 连接、稳定
- 三次握手、四次挥手
- 最少需要三次,才能保证稳定连接!
- 客户端、服务端
- 传输完成、释放完成、效率低
UPD:发短信
- 不连接、不稳定
- 客户端、服务端没有明确的界限
- 不管有没有准备好,都可以发
1.6、TCP
客户端
1.连接服务器 Socket
2.发送消息
服务端
1.建立服务的端口 ServerSocket
2.等待用户的连接 accept
3.接收消息
// 客户端
public class TcpClientDemo01 {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {
// 1.知道服务器的地址
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
// 端口
int port = 9999;
// 2.创建一个socket连接
socket = new Socket(serverIP,port);
// 3.发送消息
outputStream = socket.getOutputStream();
outputStream.write("Hellow,Server".getBytes());
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null)
{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
// 服务端
public class TcpServerDemo01 {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
//1.得有一个地址
serverSocket = new ServerSocket(9999);
//2.等待客户端连接
socket = serverSocket.accept();
// 3.读取客户端的消息
inputStream = socket.getInputStream();
// 管道流
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len=inputStream.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(byteArrayOutputStream.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
// 关闭资源
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件上传
public class TcpClientDemo02 {
public static void main(String[] args) throws Exception {
// 1.创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
// 2.创建一个输出流
OutputStream outputStream = socket.getOutputStream();
// 3.读取文件
FileInputStream fis = new FileInputStream(new File("QQ截图20191003223254.png"));
// 4.写出文件
byte[] bytes = new byte[1024];
int len;
while ((len=fis.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
// 通知服务器已经传输结束
socket.shutdownOutput();
// 确定接收成功后才能关闭连接
InputStream is = socket.getInputStream();
// String byte[]
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
byte[] bs = new byte[1024];
int len2;
while ((len2=is.read(bs))!=-1){
byteArrayOutputStream.write(bs,0,len2);
}
System.out.println(byteArrayOutputStream.toString());
//5.关闭资源
byteArrayOutputStream.close();
is.close();
fis.close();
outputStream.close();
socket.close();
}
}
public class TcpServerDemo02 {
public static void main(String[] args) throws Exception {
// 1.创建服务
ServerSocket serverSocket = new ServerSocket(9000);
// 监听客户端的连接
Socket socket = serverSocket.accept();
// 获取输入流
InputStream inputStream = socket.getInputStream();
// 文件输出
FileOutputStream fileOutputStream = new FileOutputStream(new File("receive.png"));
byte[] bytes = new byte[1024];
int len;
while ((len=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
// 通知客户端接收成功
OutputStream os = socket.getOutputStream();
os.write("ok".getBytes());
os.close();
fileOutputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
1.7、UDP
// 不需要连接服务器
public class UdpClientDemo01 {
public static void main(String[] args) throws Exception {
// 1.建立一个连接
DatagramSocket datagramSocket = new DatagramSocket();
// 2.建一个包
String msg = "Hellow,Server!";
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port =9000;
// param:数据,数据的长度
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length,inetAddress,port);
// 3.发送包
datagramSocket.send(datagramPacket);
datagramSocket.close();
}
}
// 还是要等待客户端的响应
public class UdpServerDemo01 {
public static void main(String[] args) throws Exception {
// 开放端口
DatagramSocket datagramSocket = new DatagramSocket(9000);
// 接收包
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
datagramSocket.receive(datagramPacket);// 阻塞接收
System.out.println(datagramPacket.getAddress().getHostAddress());
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
datagramSocket.close();
}
}
UDP实现多线程在线聊天
public class TalkSend implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
private int fromPort;
private String toIP; // 接收方的IP
private int toPort; // 接收方的端口
public TalkSend(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
String data = reader.readLine();
byte[] bytes = data.getBytes();
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress(this.toIP,this.toPort));
socket.send(packet);
if(data.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class TalkReceive implements Runnable {
DatagramSocket socket = null;
private int port; // 接收方的端口
private String msgName; // 发送方的姓名
public TalkReceive(int port,String msgName) {
this.port = port;
this.msgName = msgName;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
// 准备接收包裹
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
socket.receive(packet);// 阻塞式接收包
// 断开连接
byte[] data = packet.getData();
String receiveData = new String(data,0,data.length);
// 打印对方的信息
System.out.println(msgName+":"+receiveData);
if(receiveData.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Student {
public static void main(String[] args) {
// 开启两个线程
new Thread(new TalkSend(7777,"127.0.0.1",9999)).start();
new Thread(new TalkReceive(8888,"Teacher")).start();
}
}
public class Teacher {
public static void main(String[] args) {
// 开启两个线程
new Thread(new TalkSend(5555,"127.0.0.1",8888)).start();
new Thread(new TalkReceive(9999,"Student")).start();
}
}
1.8、URL
统一资源定位符:定位互联网上的某一个资源。
https://www.xxx.com
DNS 域名解析 www.xxx.com -> 127.xxx.xxx.xxx(ip)
协议://ip地址:端口号/项目名/资源
// 下载网络资源
public class URLDown {
public static void main(String[] args) throws Exception {
// 下载地址
URL url = new URL("http://xxxxxxxxx");
// 连接到这个资源
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("XXX.txt");
byte[] bytes = new byte[1024];
int len;
while ((len=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
fileOutputStream.close();
inputStream.close();
urlConnection.disconnect();
}
}