网络通信入门
前言
网络通信就是解决不同的程序,不同的计算机之间进行数据的交换问题,在一定协议下实现两台计算机的通信。常见的结构有C/S和B/S结构,C/S是客户端服务器架构,B/S是浏览器服务器架构。
一、网络通信常见概念
IP地址
指的是互联网的协议地址,给网络中每一台计算机设备做唯一编号使用,分为IPV4和IPV6两种协议。
IPV4协议:由32二位二进制数组成,通常被分为四个字节以10进制数字,既a.b.c.d形式,其中a.b.c.d的10进制取值范围都是0-255(对应二进制的00000000-11111111。但是采用IPV4协议分配地址数量显然不能够满足日益增加的设备,于是一种能够分配更多地址的协议IPV6诞生了。
IPV6协议:由128二位二进制数组成,通常被分为8个组,每组由16位二进制数组成,可以用ABCD:EF01:2345:6789:ABCD:EF01:2345:6789形式表示,其中每组四位都是一个16位二进制数的16位进制表示形式,例ABCD对应二进制数1010101111001101。IPV6协议号称可以为地球上每一粒沙子分配一个IP地址。
子网掩码
子网掩码需要和ip地址配合一起使用,其由32二位二进制数组成,和IPV4协议一样表现为a.b.c.d形式,其作用是区别网络标识和主机标识,并将一个大的IP网络划分为若干小的子网络避免ip地址浪费。
子网掩码一般放在主体ip地址的后面,比如192.168.12.12/255.255.255.0这种形式。
局域网,城域网,广域网
局域网:局域网是一个小型区域(公司,社区)内所有设备形成的网络,范围比较小,相对其他网络传输速度更快,性能更稳定,框架简易,并且是封闭性,这也是很多机构选择的原因所在。
城域网:是在一个较大范围(城市)内内所有设备形成的网络,可以由设备或者多个局域网组成。
广域网:是在一个更大范围(不同同地区,不同国家)内内所有设备形成的网络,通常跨越很大的物理范围。
DNS域名
每一个计算机都有一个唯一表示的ip地址,而且这个ip地址也不是一直不变的,那么记忆这些ip地址或者当其发生改变时要重新记忆会变得很麻烦,这时就要引出域名这个概念。域名就是用一个唯一不变的名字来指向一个ip地址,需要访问这个ip地址的时候可以输入域名,然后会向根服务器发送域名请求,根服务器会解析域名并给出一个ip地址以供访问,当ip地址发生变化时只用把新的ip地址和域名绑定就可,域名不会发生变化,这样会减少ip地址变动和记忆麻烦带来的不便。
端口号
前面讲过网络通信本质是两个程序之间的信息传输,ip地址可以确定唯一设备,但是在计算机上会有很多个程序存在,如何确定与那个程序进行通信呢,这是就引出了端口号的概念。
端口号可以唯一表示应用程序(进程),它用两个字节的整数表示,取值范围为0-65535,一共65536个端口号。
注意在使用端口号的时候要确认这个端口号没有被其他进程所使用,0-1024端口被一些知名网络服务使用,所以尽量使用靠后的端口号。
利用协议+IP地址+端口号就可以唯一标识网络中的进程并在进程之间进行通信。
二、网络通信实例
自己搭建一个服务器端并用自己写一个客户端类实现服务器允许多个客户端连接并且实时同步输出客户端输入的内容。
服务器代码:
public class MyServer {
public static void main(String[] args) throws IOException {
//创建服务器对象
ServerSocket serverSocket = new ServerSocket(12345);
//打印服务器信息
System.out.println("服务器已开启,ip为:"+serverSocket.getInetAddress()+",端口号为:"+serverSocket.getLocalPort()+"等待连接。。。");
//保证服务器不会关闭,实现多个客户端连接
while (true){
//接收连接的客户端对象
Socket client = serverSocket.accept();
//打印连接成功信息
System.out.println("客户端已连接,ip为:"+client.getInetAddress()+",端口号为:"+client.getPort());
//获取客户端对象输出流并写回连接成功信息
OutputStream outputStream = client.getOutputStream();
outputStream.write("已经建立连接".getBytes(StandardCharsets.UTF_8));
while (true) {
//获取客户端输入并打印
InputStream inputStream = client.getInputStream();
if(inputStream!=null ){
byte[] context = new byte[1024];
int len = inputStream.read(context);
if(len>0){
String msg = new String(context, 0, len);
System.out.println(msg);
}else{
break;
}
}
}
}
}
}
客户端代码:
public class MyClient {
public static void main(String[] args) throws IOException {
// 创建 Socket,输入服务器的IP地址和端口号,确定连接到哪里.
Socket client = new Socket("localhost", 12345);
// 获取输入流对象 ,接收服务器返回的建立连接信息
InputStream in = client.getInputStream();
byte[] b = new byte[100];
int len = in.read(b);
//将字节流数组转换为String
System.out.println(new String(b, 0, len));
// 获取输出流对象 ,向服务器输出消息
OutputStream outputStream = client.getOutputStream();
System.out.println("请输入要在服务器显示的内容:");
//一直循环可以实现一直输入信息
while (true) {
//控制台逐行输入
Scanner sc = new Scanner(System.in);
String str = sc.nextLine() ;
// System.out.println(str);
//写入输出流
outputStream.write(str.getBytes(StandardCharsets.UTF_8));
}
}
}
最终效果:
服务期开启:
客户端连接上服务器:
服务器显示效果:
客户端效果:
总结
以上就是今天要讲的内容,本文仅仅简单介绍了 网络通信入门知识和简单的实现客户端与服务器通信,这里仅仅是使用了一个客户端允许多此链接,后续还会使用多线程实现多个客户端同时传输文件图片等功能。