目录
可以让设备中的程序与网络上其他设备的程序进行数据交互(实现网络通信)
CS:在用户本地需要下载并安装客户端程序,在远程有一个服务器端程序
BS:只需要一个浏览器,用户通过不同的网址,客户访问不同的服务器
设备在网络中的地址,是唯一的标识
有IPv4和IPv6

最多有2^32次方的ip,目前用完了
IPv4中不够用,就有了IPv6

为了解决ipv4不够用而出现的,最多有2^128次方的ip
公网地址(万维网使用)和私有地址(局域网使用)
192.168.开头的就是私有地址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用,以此节约IP
127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也成为本机IP,永远只会寻找当前所在的本机
常用的CMD命令
ipconfig:查看本机IP地址
ping:检查网络是否连通
- public class ip {
- public static void main(String[] args) throws UnknownHostException {
- // 1.获取InetAddress的对象
- // IP的对象 一台电脑对象
- InetAddress address = InetAddress.getByName("192.168.135.1");
- System.out.println(address);
- String name = address.getHostName();
- System.out.println(name);
- String ip = address.getHostAddress();
- System.out.println(ip);
- }
- }
应用程序在设备中唯一的标识
端口号: 由两个字节表示的整数,取值范围:0-665535,其中0-1023之间的端口用于一些知名的网络服务或应用,我们自己使用1024以上的端口就可以了
数据在网路中传输的规则
UDP协议: 用户数据报协议
UDP是面向无连接通信协议
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
TCP协议:传输控制协议
TCP协议是面向连接的通信协议
速度慢,没有大小限制,数据安全
下面是用UDP来发收数据

- public class ip {
- public static void main(String[] args) throws IOException {
- // 发送数据
- // 1.创建DatagramSocket对象
- // 细节:
- //绑定端口,以后我们就是通过这个端口往外发送
- //有参:指定端口号进行绑定
- DatagramSocket ds = new DatagramSocket();
-
- // 打包数据
- String str = "hello world";
- byte[] bytes = str.getBytes(); // 将str转换成字节数组来用来打包数据
- InetAddress address = InetAddress.getByName("127.0.0.1"); // 表示那台ip电脑来接受
- int port=10086; //被发数据电脑接收的端口
- DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
-
- // 3. 发送数据
- ds.send(dp);
-
- // 4.释放资源
- ds.close();
- }
- }
- public class receive {
- public static void main(String[] args) throws IOException {
- // 接收数据
-
- // 1.创建DatagramSocket对象//我们可以做一个比喻: 这就是一个快递公司
- // 细节:
- // 接收和传输不一样:接收一定要绑定接口
- // 而且绑定的端口,一定要跟发送的端口保持一致
- DatagramSocket ds = new DatagramSocket(10086);
-
- // 2. 接收数据包
- byte[] bytes = new byte[1024];
- DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
- ds.receive(dp);
-
- // 3.解析数据包
- byte[] data = dp.getData();
- int len = dp.getLength();
- InetAddress address = dp.getAddress();
- int port = dp.getPort();
-
- System.out.println("接收到数据" + new String(data,len));
- System.out.println("该数据是从"+address+"接口是"+port);
-
- // .释放资源
- ds.close();
- }
- }
通信双方事先会采用"三次握手"方式建立可靠连接,实现端到端的通信;底层能保证数据成功传到服务端



一发一收
创建客户端
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
-
- public class Tcp {
- public static void main(String[] args) throws IOException {
- // 1.创建Socket对象,并同时请求与服务器程序的连接
- Socket socket = new Socket("127.0.0.1",8888);
-
- // 2.从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
- OutputStream os = socket.getOutputStream();
-
- // 3.把低级的字节输出流包装成数据流
- DataOutputStream dos = new DataOutputStream(os);
-
- //4.开始写数据出去了
- dos.writeUTF("在一起,好吗?");
- dos.close();
-
- socket.close();
-
- }
- }
创建服务器
- import java.io.DataInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class Res {
- public static void main(String[] args) throws IOException {
- System.out.println("------服务端启动成功------");
- // 1.创建ServerSocket的对象,同时为服务端注册端口
- ServerSocket serverSocket = new ServerSocket(8888);
- // 2.使用serverSocket对象,调用一个accept方法,等待客户端的连接请求
- Socket socket = serverSocket.accept();
-
- // 3. 从socket通信管道中得到一个字节输入流
- InputStream is = socket.getInputStream();
-
- //4.把原始的字节输入流包装成数据输入流
- DataInputStream dis = new DataInputStream(is);
-
- //5.使用数据输入流读取客户端发送的消息
- String rs = dis.readUTF();
- System.out.println(rs);
-
- // 其实我们也可以获取客户端的IP地址
- System.out.println(socket.getRemoteSocketAddress());
-
- dis.close();
- socket.close();
- }
- }
多发多收
发送数据
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
- import java.util.Scanner;
-
- public class Tcp {
- public static void main(String[] args) throws IOException {
- // 1.创建Socket对象,并同时请求与服务器程序的连接
- Socket socket = new Socket("127.0.0.1",8888);
-
- // 2.从socket通信管道中得到一个字节输出流,用来发数据给服务端程序
- OutputStream os = socket.getOutputStream();
-
-
- // 3.把低级的字节输出流包装成数据流
- DataOutputStream dos = new DataOutputStream(os);
-
- Scanner sc = new Scanner(System.in);
-
-
- while (true) {
- System.out.println("请说: ");
- String msg = sc.nextLine();
- // 一旦用户输入exit,就退出客户端程序
- if("exit".equals(msg)){
- System.out.println("欢迎你下次光临!退出成功");
- dos.close();
- socket.close();
- break;
- }
- //4.开始写数据出去了
- dos.writeUTF(msg);
- dos.flush();
- }
- }
- }
接收数据
- import java.io.DataInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class Res {
- public static void main(String[] args) throws IOException {
- System.out.println("------服务端启动成功------");
- // 1.创建ServerSocket的对象,同时为服务端注册端口
- ServerSocket serverSocket = new ServerSocket(8888);
- // 2.使用serverSocket对象,调用一个accept方法,等待客户端的连接请求
- Socket socket = serverSocket.accept();
-
- // 3. 从socket通信管道中得到一个字节输入流
- InputStream is = socket.getInputStream();
-
- //4.把原始的字节输入流包装成数据输入流
- DataInputStream dis = new DataInputStream(is);
-
- while (true) {
- try {
- //5.使用数据输入流读取客户端发送的消息
- String rs = dis.readUTF();
- System.out.println(rs);
- } catch (IOException e) {
- System.out.println(socket.getRemoteSocketAddress()+"离线了");
- socket.close();
- dis.close();
- break;
- }
- }
-
-
- }
- }

我们应该整一个多线程的写法,每个客户端写成一个线程
创建客户端
- public class tcp {
- public static void main(String[] args) throws IOException {
- Socket socket = new Socket("127.0.0.1",9999);
- OutputStream os = socket.getOutputStream();
- DataOutputStream dos = new DataOutputStream(os);
- // 1. 多发多收
- Scanner sc = new Scanner(System.in);
-
- while (true) {
- String msg = sc.nextLine();
- if("886".equals(msg)){
- System.out.println("下线");
- break;
- }
- dos.writeUTF(msg);
- }
- }
- }
创建服务端
- public class res {
- public static void main(String[] args) throws IOException {
- ServerSocket serverSocket =new ServerSocket(9999);
- while (true) {
- Socket socket = serverSocket.accept();
- System.out.println("有人上线了"+socket.getRemoteSocketAddress());
- new SeverSocketThread(socket).start();
- }
- }
- }

我们看看线程的写法
- package TCP_test;
-
- import java.io.DataInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class SeverSocketThread extends Thread{
- private Socket socket;
-
- public SeverSocketThread(Socket socket) {
- this.socket = socket;
- }
- @Override
- public void run()
- {
- try {
- InputStream is = socket.getInputStream();
- DataInputStream dis = new DataInputStream(is);
- while (true) {
- try {
- String msg = dis.readUTF();
- System.out.println(msg);
- } catch (Exception e) {
- System.out.println("有人下线了"+socket.getRemoteSocketAddress());
- dis.close();
- is.close();
- socket.close();
- break;
- }
- }
- } catch (IOException e) {
- System.out.println(socket.getRemoteSocketAddress() + "下线");
- }
- }
- }