目录
(1) ip (Internet Protocol Address) :
1.计算机网络
把分布在不同地理区域的具有独立功能的计算机,通过通信设备与线路连接起来,由功能完善的软件实现资源共享和信息传递的系统。网络编程的目的是直接或间接地通过网络与其它计算机实现数据交换。
2.网络通讯模型
应用层(数据)----传输层(协议)----网络层(ip+端口)----数据链路层(实际通讯设备 网线 光纤)
3.网络通讯基本要素
(1) ip (Internet Protocol Address) :
计算机网络协议地址 , 连接路由器 , 路由器会为我们的电脑分配一个唯一的ip地址
查看ip地址的方法 : win+R----输入cmd----输入ipconfig----回车
ip地址 : 局域网地址:192.168.xx.xx 本地回环地址:127.0.0.1(指向自己的电脑)
(2) 端口 :
电脑上的每一个应用程序(QQ 微信)都会有一个唯一的端口号(整数 取值范围为0~65535)
端口号举例 : MySQL(3306) SQLServer(1433) Oracle(1521)
注意 : 理解 端口号 和 IP :
(3) 通讯协议 :
1.定义
计算机网络通信时必须实现的一些约定(通信协议)
对速率 传输代码 代码结构 传输控制步骤 出错控制 等制定标准
2.分类:
a. 传输控制协议TCP
Transmission Control Protocol 采用两个应用进程(服务端和客户端)
a1. 三次握手和四次挥手
(传输前)三次握手 : 检查网络是否通畅,如果网络通畅才进行数据传输
(断开时)四次挥手 : 相比UDP协议更可靠,但是效率较低
a2. Socket套接字
Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
两台机器间通信的端点是Socket. 通信的两端都要有Socket
网络通信其实就是Socket间的通信
发送纯文本:
package TCP.TCPsocket;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1",9999);//(ip地址,端口号)
Scanner scanner = new Scanner(System.in);
while(true){ System.out.println("客户端输入:");
String s = scanner.next();
//IO 通过socket获得输出流对象,从客户端向服务器发送消息
OutputStream outputStream = socket.getOutputStream();//节点流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);//数据处理流
dataOutputStream.writeUTF(s);
//在客户端接收服务器发送的消息
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
}
}catch(IOException e){
System.out.println("服务端链接失败");
e.printStackTrace();//打印异常信息
}
}
}
package TCP.TCPsocket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {//先启动服务器,在启动客户端(服务器必须事先建立一个等待客户请求建立套接字连接的ServerSocket对象)
public static void main(String[] args) {
try { //创建服务器套接字,并绑定到指定的端口上
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端起启动成功");
//监听客户端链接,接收成功返回套接字对象
Socket socket =serverSocket.accept();
System.out.println("客户端链接成功");
Scanner scanner = new Scanner(System.in);
//在服务器接收客户端发送的消息
while (true){
//调用该Socket类对象的 getOutputStream()和getInputStream():获取输出流和输入流,进行网络数据的发送和接收。
InputStream inputStream= socket.getInputStream();
DataInputStream dataInputStream =new DataInputStream(inputStream);//数据处理流,将其转为String类型的字符串
String msg = dataInputStream.readUTF();
System.out.println(msg);
//从服务器向客户端发送信息
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
System.out.println("服务器端输入:");
String s = scanner.next();
dataOutputStream.writeUTF(s);
}
}catch (IOException e) {
System.out.println("客户端链接失败");
e.printStackTrace();//打印异常信息
}
}
}
流程分析:
发送文件(图片):
package TCP.TCPfilesocket;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
FileInputStream inputStream = new FileInputStream("D:a.png");//要发送给服务器的文件(图片 纯文本...)
Socket socket = new Socket("127.0.0.1",9999);//(服务器ip,服务器端口)
OutputStream outputStream = socket.getOutputStream();//输出流,发送到服务器
byte[] bytes = new byte[100];
int length = 0;
while((length=inputStream.read(bytes))!=-1){//读取要发送的文件
outputStream.write(bytes,0,length);
}
socket.shutdownInput();//发送文件时需要调用,表示发送完成
inputStream.close();
outputStream.close();
} catch (UnknownHostException e) {
System.out.println("ip不正确");
} catch (FileNotFoundException e) {
System.out.println("文件找不到");
} catch (IOException e) {
System.out.println("系统匆忙,请稍后再试");
}
}
}
package TCP.TCPfilesocket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket();
Socket socket = serverSocket.accept();//监听客户端链接
FileOutputStream fileOutputStream = new FileOutputStream("D:/a.txt");//服务器端 接收文件的地址
InputStream inputStream =socket.getInputStream();
byte[] bytes = new byte[100];
int length=0;
while ((length=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,length);
}
DataOutputStream dataoutputStream = new DataOutputStream(socket.getOutputStream());//数据处理流
dataoutputStream.writeUTF("接收成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
b. 用户数据报协议UDP
User Datagram Protocol
将数据、源(发送者IP)、目的地(接受者IP) 封装成数据包,不需要建立连接就可以发送(不可靠),如果网络有问题,没有任何反馈 不存在服务器和客户端,只有发送端和接受端
发送者:
package UDP;
import java.io.IOException;
import java.net.*;
public class Send { //发送者
public static void main(String[] args) {
try {
DatagramSocket datagramSocket = new DatagramSocket();//发送端这里不需要写端口号,因为数据包中有
byte[] bytes = "你好".getBytes();//将字符串转为字节数组
//DatagramPacket用于封装, DatagramSocket用于发送和接收
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("127.0.0.1"),9999);
// 数据包 要封装数组 数组的长度 IP 端口号
datagramSocket.send(datagramPacket);//要发送的数据包
}catch (SocketException e){
throw new RuntimeException(e);
}catch (UnknownHostException e){
throw new RuntimeException(e);
}catch (IOException e){
throw new RuntimeException(e);
}
}
}
接收者
package UDP;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Recieve { //接受者
public static void main(String[] args) {
try {//创建一个发送接收对象,需要写端口号
DatagramSocket datagramSocket = new DatagramSocket(9999);
byte[] bytes = new byte[100];//创建数组
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);//数据包对象
datagramSocket.receive(datagramPacket);//接收数据到数据包(bytes数组)中
String s = new String(bytes,0,datagramPacket.getLength());
System.out.println(s);
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}