网络编程
计算机网络的概述
我们把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模宏大、功能强大的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。
网络分类
按照网络规模和范围可以简单划分为:
- 局域网(LAN,Local Area Network)
- 都市网(MAN,Metropolis Area Network)
- 广域网(WAN,Wide Area Network)
按照网络拓扑结构可以分为:
- 星型网络、总线网络、环线网络、树型网络、星型环线网络等
按照传输介质划分:
- 双绞线、同轴电缆、光导纤维、视线介质等
IP&Port
IP(Internet Protocol):网络中主机的唯一标识,通过Ip可以定位到主机地址,其中IP又被分为IPV4和IPv6
Port:端口,是主机中应用程序的唯一标识,是应用程序跟外界通信,交流的出入口
Socket通信
Socket(套接字)是主机中ip和端口结合,通过Socket可以轻松实现不同主机之间应用程序的通信,可以通俗的理解为不同主机中相同软件的的通信桥梁,关于计算机应用的通信模式分为以下两种:
- C/S架构:客户端(Client)/服务端(Server)模式
- B/S架构:浏览器(Browser)/服务器(Server)模式
基于TCP/IP的Socket通信原理
TCP/IP是一个安全可靠的传输协议,需要保证两个通信端点之间的稳定连接,并且也能保证数据传输的完整性还有顺序,Java中基于TCP/IP编程主要通过以下两个类完成:
- java.net.ServerSocket 用于表示服务端套接字
- java.net.Socket 用户表示客户端套接字
主要代码
服务端
- 占据8888端口创建一个服务
ServerSocket server = new ServerSocket(8888);
- 开始监听,一旦客户端连接则返回Socket对象
Socket s = server.accept();
客户端
- 连接到指定ip,指定端口的服务
Socket s = new Socket("192.168.4.198",8888);
- 获取基于Socket的字节输入流
InputStream is = s.getInputStream();
- 将字节流转换为字符流
InputStreamReader isr = new InputStreamReader(is);
- 将低级字符流转换为缓冲流
BufferedReader br = new BufferedReader(isr);
String msg = br.readLine();
- 输出
System.out.println(msg);
基于UDP协议的Socket通信
UDP(User Datagram Protocol),用户数据报协议,不是一个基于稳定连接的协议,使用UDP协议通信不需要通信的两个端点间建立连接,通信的端点既可以作为发送端也可以作为接收端;与TCP 协议之间的不同在于, UDP 不是一种基于稳定连接的通讯协议。UDP 协议将独立的数据包从一台计算机传 输到另外一台计算机,但是并不保证接受方能够接收到该数据包,也不保证接收方 所接收到的数据和发送方所发送的数据在内容和顺序上是完全一致的。因此,UDP 协议更类似于快递的邮寄,快递的投递不能够保证能够被接收方及时收到,后发出的包裹也许会比先发出的包裹更早到达。
Java中也提供了两个用于实现UDP通信的核心类:
- java.net.DatagramPacket
- java.net.DatagramSocket
具体使用方法
-
发送方
String msg = "锄禾日当午,汗滴禾下土"; //创建一个网络通道 DatagramSocket ds = new DatagramSocket(); //创建数据报包 //1.需要发送消息的字节数组 //2.数组中字节的偏移量,从头开始发送设置为0 //3.需要发送的字节长度 //4.接收方的ip地址 //5.接收方应用程序的端口 DatagramPacket dp = new DatagramPacket( msg.getBytes(), 0, msg.getBytes().length, InetAddress.getByName("192.168.4.198"), 5678); //发送 ds.send(dp);
-
接收方
//创建一个网络通道,占据5678端口
DatagramSocket ds = new DatagramSocket(5678);
//声明字节缓冲区,用于存储从通道中获取的字节数据
byte[] b = new byte[1024];
//声明一个数据报包(空)接收通过中传输过来的数据
DatagramPacket dp = new DatagramPacket(b, b.length);
//接收
ds.receive(dp);
System.out.println("");
//将字节数组中的有效数据解析为字符串
String s = new String(b,0,dp.getLength());
System.out.println("msg:"+s);