章节14:网络编程
- 【1】网络编程的概念
- 【2】IP地址与端口的概念
- 【3】网络通信协议
- 引入
- 网络通信协议的分层
- 【3】Socket套接字
- 【4】单向通信
- 【5】双向通信
【1】网络编程的概念
把分布在不同地理区域的计算机与专门的外部设备用通信线路互联成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享硬件、软件、数据信息等资源。设备之间在网络中进行数据的传输,发送/接收数据。
【2】IP地址与端口的概念
- IP地址:用来标志网络中的一个通信实体的地址。通信实体可以是计算机,路由器等。
- 端口号:IP地址用来标志一台计算机,但是一台计算机上可能提供多种应用程序,使用端口来区分这些应用程序。
【3】网络通信协议
引入
计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等指定标准。
由于结点间联系复杂,制定协议时,把复杂成分分解成一些简单的成分,再讲它们复合起来。最长用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。
网络通信协议的分层
- 名义上的标准:ISO/OSI参考模型(但实际上只停留在实验室,停留在理论讲解,实际上没有得到应用,并没有实际的产品出来)
ISO/OSI参考模型 | 一共7层 |
---|---|
应用层 | 程序实现需求 |
表示层 | 解决不同系统之间的通信问题:比如Linux给Windows发包 |
会话层 | 自动发包,自动寻址功能 |
传输层 | 当传输的内容过大时,对发出去的数据进行封装 |
网络层 | 传输过程中选择最优路径(就是路由器,交换机那些具有寻址功能的设备所实现的功能) |
数据链路层 | 确保数据传输正确,提供检测和纠错功能 |
物理层 | 定义物理设备的标准:网线的接口类型,光纤的接口类型,各种传输介质的传输速率;数据最终变成01串从物理设备中传输出去 |
- 事实上的标准:TCP/IP协议栈(Internet使用的协议)
TCP/IP协议 | 一共4/5层 |
---|---|
应用层 | 负责应用程序间的数据通讯。最常见的协议为DNS和HTTP |
传输层 | 负责两台主机间的数据传输。常见协议为TCP和UDP |
网络层 | 自动发包,自动寻址功能 |
数据链路层 | 负责设备之间的数据帧的传送和识别 |
物理层(可选) | 负责将数据转换成信号,再将信号转换为数据 |
【3】Socket套接字
程序员开发的网络应用程序位于应用层,如果要使用网络,只需要与传输层交接即可,可以把传输层理解为快递员,程序员寄快递只需要把快递给快递员,至于快递怎么运输的不用管。
在应用层如何使用传输层的服务呢?Socket套接字就是应用层与传输层之间的桥梁,应用程序通过这个桥梁向远程发送或接收远程数据。
【4】单向通信
先创建一个服务器端
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) throws IOException {
System.out.println("服务器端启动");
//套接字,IP默认为本地网络IP,端口号随便设置一个,但要保证服务器端与客户端一致
ServerSocket ss = new ServerSocket(1234);//此处的异常抛出即可
//等待客户端发送数据
Socket s=ss.accept();
//本例中服务器要接受数据则创建输入流
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
//接受客户端发送的数据
String str=dis.readUTF();
System.out.println(str);
//倒序依次关闭流与网络资源
dis.close();
is.close();
s.close();
ss.close();
}
}
运行,让服务器端启动,服务器会一直等待客户端发送的数据
再创建一个客户端
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class TestClient {
public static void main(String[] args) throws IOException {
System.out.println("客户端启动");
//套接字:指定服务器的ip和端口号
Socket s=new Socket("10.67.3.131",1234);
//本例通过客户端发送数据,创建输出流
OutputStream os=s.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
//发送数据
dos.writeUTF("你好");
//关闭流、网络资源
dos.close();
os.close();
s.close();
}
}
运行客户端,可以看到客户端发送完数据后关闭了
这时发现服务器端接收到了数据
【5】双向通信
服务器端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) throws IOException {
System.out.println("服务器端启动");
//套接字,IP默认为本地网络IP,端口号随便设置一个,但要保证服务器端与客户端一致
ServerSocket ss = new ServerSocket(1234);//此处的异常抛出即可
//等待客户端发送数据
Socket s=ss.accept();
//本例中服务器要接受数据则创建输入流
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
//接受客户端发送的数据
String str=dis.readUTF();
System.out.println(str);
//向客户端发送数据
OutputStream os=s.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
dos.writeUTF("你好客户端,我是服务器,我收到了你的消息");
//倒序依次关闭流与网络资源
dos.close();
os.close();
dis.close();
is.close();
s.close();
ss.close();
}
}
客户端
import java.io.*;
import java.net.Socket;
public class TestClient {
public static void main(String[] args) throws IOException {
System.out.println("客户端启动");
//套接字:指定服务器的ip和端口号
Socket s=new Socket("10.67.3.131",1234);
//本例通过客户端发送数据,创建输出流
OutputStream os=s.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
//发送数据
dos.writeUTF("客户端:你好");
//接收服务器端发来的数据
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
String str=dis.readUTF();
System.out.println("服务器端:"+str);
//关闭流、网络资源
dis.close();
is.close();
dos.close();
os.close();
s.close();
}
}