网络编程学习笔记
一、网络编程
1.计算机网络简介:
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。如图1所示。
图1(图片来源:网络)
2.网络编程简介:
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换
3.网络模型:
计算机网络之间以何种规则进行通信,就是网络模型研究问题。网络模型有两种:
OSI(OpenSystem Interconnection开放系统互连)参考模型
TCP/IP参考模型
网络模型参考图,如图2所示:
图2
4.OSI模型的介绍:
1.物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流。这一层的数据叫做比特。
2. 数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。常把这一层的数据叫做帧。在这一层工作的设备是交换机,数据通过交换机来传输。
3. 网络层:主要将从下层接收到的数据进行IP地址(例192.168.0.1)的封装与解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包。
4. 传输层:定义了一些传输数据的协议和端口号(WWW端口80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。
5.会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
6.表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等)。
7.应用层:主要是一些终端的应用,比如说FTP(各种文件下载),WEB(IE浏览),QQ之类的(可以把它理解成我们在电脑屏幕上可以看到的东西.就是终端应用)。
5.网络通信三要素
IP地址:InetAddress
网络中设备的标识,不易记忆,可用主机名
端口号
用于标识进程的逻辑地址,不同进程的标识
传输协议
通讯的规则,常见协议:TCP,UDP
6.IP地址详解
要让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。
所谓IP地址就是给每个连接在Internet上的主机分配的一个32bit地址。按照TCP/IP规定,IP地址用二进制来表示,每个IP地址长32bit,比特换算成字节,就是4个字节。例如一个采用二进制形式的IP地址是“00001010000000000000000000000001”。为了方便使用,IP地址经常被写成十进制的形式,中间使用符号“.”分开不同的字节。于是,上面的IP地址可以表示为“10.0.0.1”。IP地址的这种表示法叫做“点分十进制表示法”。
IP地址的组成
IP地址 = 网络号码+主机地址
IP地址的常用分类:
A类IP地址:第一段号码为网络号码,剩下的三段号码为本地计算机的号码
255*255*255= 16581375
B类IP地址:前二段号码为网络号码,剩下的二段号码为本地计算机的号码
255*255= 65535
C类IP地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码
255
IP地址的具体分类
A类 1.0.0.1---127.255.255.254 (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)。
主要用于欧美国家的一些世界500强的公司。
B类 128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。
主要用于大学
C类 192.0.0.1---223.255.255.254 192.168.X.X是私有地址
国内公司的局域网常用。
D类 224.0.0.1---239.255.255.254,保留地址,实验用
E类 240.0.0.1---247.255.255.254,保留地址,实验用
特殊地址:
127.0.0.1 回环地址,可用于测试本机的网络是否有问题:ping127.0.0.1
7.如何获取和操作IP地址呢?
java提供了一个类InetAddress方便对IP地址的获取和操作。
8.什么是DNS?
DNS(DomainName System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
9.DOS命令
ipconfig:查看计算机网络配置信息
ipconfig /all:查看详细的计算机网络配置信息
二、InetAddress类
1.简介:
此类表示互联网协议 (IP) 地址,IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。从JDK1.0。
2.构造方法:
无,可通过API中的几个static方法,返回一个InetAddress类对象。
3.常用方法:
public static InetAddress getByName(String host)//在给定主机名的情况下确定主机的 IP 地址,获取任意主机。
public StringgetHostName()//获取此 IP 地址的主机名
public StringgetHostAddress()//返回IP地址字符串(以文本表现形式)。
测试代码:
public class InetAddressDemo{
public static voidmain(String[] args)
throwsUnknownHostException {
//1、根据主机名获取IP地址
//InetAddress address =InetAddress.getByName("x-PC");
InetAddress address1 = InetAddress.getByName("192.168.0.108");
//2、根据IP地址获取主机名
String name = address1.getHostName();
System.out.println(name);
//3、获取IP地址字符串
String str = address1.getHostAddress();
System.out.println(str);
}
}
4.端口号
简介:在网络技术中,端口(Port)包括逻辑端口和物理端口两种类型。物理端口指的是物理存在的端口,如ADSL Modem、集线器、交换机、路由器上用于连接其他网络设备的接口,如RJ-45端口、SC端口等等。逻辑端口是指逻辑意义上用于区分服务的端口,如TCP/IP协议中的服务端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等。由于物理端口和逻辑端口数量较多,为了对端口进行区分,将每个端口进行了编号,这就是端口号。
注意:每个网络程序都会至少有一个逻辑端口,用于标识进程的逻辑地址,不同进程的标识。有效端口:0~65535,其中0~1024系统使用或保留端口。
Dos命令查看方式:netstat–a,如图3所示。
图3
三、协议
1.UDP协议简介:将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快
2.TCP协议简介:建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低。
3.TCP和UDP的区别
udp:面向无连接,不可靠,速度快,将数据封包传输,数据包最大64k。
tcp:面向连接,安全可靠,效率稍低,通过三次握手确保连接的建立。
四、Socket套接字
简介:网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
Socket原理机制:
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输
Socket机制图解
如图4所示。
图4
五、UDP传输:
5.1简介:
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。
5.2. UDP协议发送接收数据的步骤:
1.建立DatagramSocket端口与DatagramPacket数据包
2.建立发送端,接收端。
3.建立数据包。
4.调用Socket的发送接收方法。
5.关闭Socket。
6.发送端与接收端是两个独立的运行程序
5.3 UDP传输-发送端思路
1.建立udp协议发送端socket对象
2.将要发送的数据封装成数据包对象
3.通过udp的socket服务,将数据包发送出
4.关闭资源
5.4 UDP传输-接收端思路
1.建立udp的socket服务.
2.通过receive方法接收数据
3.将收到的数据存储到数据包对象中
4.通过数据包对象的功能来完成对接收到数据进行解析.
5.可以对资源进行关闭
DatagramSocket类
简介:此类表示用来发送和接收数据报包的套接字。从JDK1.0开始。
构造方法:
public DatagramSocket() //构造数据报套接字并将其绑定到本地主机上任何可用的端口
常用方法:
public void send(DatagramPacket p) //从此套接字发送数据报包
public void close() //关闭此数据报套接字。
public void receive(DatagramPacket p) //从此套接字接收数据报包
DatagramPacket类
简介:此类表示数据报包,数据报包用来实现无连接包投递服务。从JDK1.0开始。
构造方法:
public DatagramPacket(byte[] buf,int length,InetAddress address,int port)//构造数据报包,用来将长度为 length
的包发送到指定主机上的指定端口号
//参数说明:buf:包数据。Length:包长度。Address:目的地址。Port:目的端口号
public DatagramPacket(byte[] buf,int length) //构造 DatagramPacket,用来接收长度为 length 的数据包。length 参数必须小于等于 buf.length。
常用方法:
public byte[] getData() //返回数据缓冲区
public InetAddress getAddress() //返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的
public int getLength() //返回将要发送或接收到的数据的长度
5.6UDP案例测试案例
//发送端
public class UDPSend {
public static void main(String[] args) throws IOException {
//1、建立udp的发送端socket服务
DatagramSocketds = newDatagramSocket();
//2、将要发送的数据封装成数据包
byte[]buf = "hello,world".getBytes();
int length = buf.length;
InetAddress address = InetAddress.getByName("192.168.0.108");
int port = 10086;
DatagramPacketdg = new DatagramPacket(buf,length, address,port);
//3、通过Socket对象发送数据报包数据
ds.send(dg);
//4、关闭Socket对象
ds.close();
}
}
//接收端
public class UDPReceive {
public static void main(String[] args) throws IOException {
//1、创建UDP协议的接收端Socket对象
DatagramSocketds =new DatagramSocket(10086);
//2、创建一个空的数据报包,用来存储接收的数据
byte[]buf = newbyte[1024];
int length = buf.length;
DatagramPacketdp = new DatagramPacket(buf,length);
//3、接收数据报包
ds.receive(dp);
//4、拆开数据报包,看内容
byte[]data = dp.getData();
//获取发送端的IP
InetAddress address = dp.getAddress();//返回字符串类型IP地址。
String ip = address.getHostAddress();//保存i地址
//获取数据长度
int lenth = dp.getLength();
//把字节数组转换成字符串
String str = new String(data ,0 ,lenth );
//打印收到的数据和ip
System.out.println("ip:"+ip+"..."+"data:"+str);
//5、关闭Socket对象
}
}
六、TCP传输
6.1简介:TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来.
6.2 TCP协议发送接收数据的步骤
Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
同样,客户端与服务器端是两个独立的应用程序。
6.3 TCP传输-客户端思路
1.建立客户端的Socket服务,并明确要连接的服务器。
2.如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
3.通过Socket对象的方法,可以获取这两个流
4.通过流的对象可以对数据进行传输
5.如果传输数据完毕,关闭资源
6.4TCP传输-服务器端思路
1.建立服务器端的socket对象,并指定服务器端口号
2.服务器端等待客户端Socket的连接,当有客户端Socket对象访问服务器时,通过accept()方法获取到客户端的Socket对象
3.通过获取到了客户端Socket对象,获取客户端传过来的数据
4.如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
6.5TCP常用的类和方法
ServerSocket类
简介:此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
构造方法:
public ServerSocket() //创建非绑定服务器套接字
public ServerSocket(int port) //创建绑定到特定端口的服务器套接字
常用方法:
public Socket accept() //服务器等待客户端的连接
public void close() //关闭此套接字
Socket类
简介:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
构造方法:
public Socket(InetAddress address,int port) //创建一个流套接字并将其连接到指定 IP 地址的指定端口号
public Socket(String host,int port) //创建一个流套接字并将其连接到指定主机上的指定端口号
常用方法:
public InputStream getInputStream()//返回此套接字的输入流
public OutputStream getOutputStream()//返回此套接字的输出流
public InetAddress getInetAddress()//返回套接字连接的地址
public void shutdownOutput()//禁用此套接字的输出流,告诉服务器客户端数据发送完毕
6.6TCP测试案例:
//服务器端
public class TCPServer {
public static void main(String[] args) throws IOException {
//1:建立服务器端的socket服务,并监听指定的端口号
ServerSocket ss =newServerSocket(8888);
//2、等待客户端Socket的连接
Socket s = ss.accept(); //获取连接过来的客户端对象, accept()方法是阻塞式的,没有连接就会一直等待。
System.out.println("一个连接已经建立!!!");//执行到这说明服务器已经收到客户端的连接
String ip = s.getInetAddress().getHostAddress();//获取客户端IP
System.out.println("客户端IP是:"+ip);//打印客户端IP地址
//3: 通过客户端Socket对象,获取数据
//a: 获取输入流对象
BufferedReaderbr = new BufferedReader(newInputStreamReader(s.getInputStream()));
//b: 通过输入流,获取流中的数据
String line = br.readLine();
//c: 显示数据
System.out.println("服务器端接收得的数据:" +line);
//4: 关闭Socket对象
s.close();//客户端传输完数据后,关闭客户端的连接,
//ss.close();//服务器端一般一直在线
}
}
//客户端
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//1、创建客户端Socket对象,指定要连接的服务器和端口对应的程序
Socket s = new Socket("192.168.25.122", 8888);
//注意:客户端一旦创建了Socket对象(有参),该对象就会自动向服务器端发送连接请求,如果连接不成功则程序立即终止。
//因此在TCP的客户端是找不到请求连接的代码,但是在服务器端却存在监听客户端连接请求的代码:ss.accept()
System.out.println("我已连接上服务器");//执行到本行表示已经连到服务器
//2、准备要发送的数据
String data = "hello server";
//3: 获取Socket对象中的输出流对象,然后通过输出流对象,写出数据
BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write(data);
bw.newLine();
bw.flush();//字符流传输时,必须刷新
//4: 传输数据完毕,关闭资源
bw.close();
s.close();
}
}