上图中,TCP/IP协议中的四层分别是应用层、传输层、网络层和链路层,每层分别负责不同的通信功能,接下来针对这四层进行详细地讲解。
链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网线提供的驱动。
网络层:网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。
传输层:主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议。
应用层:主要负责应用程序的协议,例如HTTP协议、FTP协议等。
1.1IP地址和端口号
要想使网络中的计算机能够进行通信,必须为每台计算机指定一个标识号,通过这个标识号来指定接受数据的计算机或者发送数据的计算机。
在TCP/IP协议中,这个标识号就是IP地址,它可以唯一标识一台计算机,目前,IP地址广泛使用的版本是IPv4,它是由4个字节大小的二进制数来表示,如:00001010000000000000000000000001。由于二进制形式表示的IP地址非常不便记忆和处理,因此通常会将IP地址写成十进制的形式,每个字节用一个十进制数字(0-255)表示,数字间用符号“.”分开,如 “192.168.1.100”。
随着计算机网络规模的不断扩大,对IP地址的需求也越来越多,IPV4这种用4个字节表示的IP地址面临枯竭,因此IPv6便应运而生了,IPv6使用16个字节表示IP地址,它所拥有的地址容量约是IPv4的8×1028倍,达到2128个(算上全零的),这样就解决了网络地址资源数量不够的问题。
通过IP地址可以连接到指定计算机,但如果想访问目标计算机中的某个应用程序,还需要指定端口号。在计算机中,不同的应用程序是通过端口号区分的。端口号是用两个字节(16位的二进制数)表示的,它的取值范围是0~65535,其中,0~1023之间的端口号用于一些知名的网络服务和应用,用户的普通应用程序需要使用1024以上的端口号,从而避免端口号被另外一个应用或服务所占用。
接下来通过一个图例来描述IP地址和端口号的作用,如下图所示。
1.1InetAddress
public class Example01{
public static void main(String[] args) throws Exception {
InetAddress local = InetAddress.getLocalHost();
InetAddress remote = InetAddress.getByName("www.itcast.cn");
System.out.println("本机的IP地址:" + local.getHostAddress());
System.out.println("itcast的IP地址:" + remote.getHostAddress());
System.out.println("itcast的主机名为:" + remote.getHostName());
}
}
TCP/UDP
UDP:(适用于即时通信(QQ聊天 对数据准确性和丢包要求比较低,但速度必须快),在线视频(RTSP 速度一定要快,保证视频连续,但是偶尔花了一个图像帧,人们还是能接受的),网络语音电话(VoIP 语音数据包一般比较小,需要高速发送,偶尔断音或串音也没有问题)等等。)
1,将数据和源及目的封装在数据包中,不需要建立连接
2,每个数据包的大小限制在64k内
3,因无连接,是不可靠协议
4,不需要建立连接,速度快
TCP:(对准确率要求较高,适用于文件传输。邮件发送、上传,下载等)
1.建立连接,行程传输数据的通道
2.在连接中形成大数据量传输
3.通过三次握手完成连接,是可靠协议
4.必须建立连接,是可靠协议
UDP:
要实现UDP通信需要创建一个发送端程序和一个接收端程序,很明显,在通信时只有接收端程序先运行,才能避免因发送端发送的数据无法接收,而造成数据丢失。因此,首先需要来完成接收端程序的编写。
UDP完成数据的发送
/*
*发送端
* 1,创建DatagramSocket对象
* 2,创建DatagramPacket对象,并封装数据
* 3,发送数据
* 4,释放流资源
*/
public class UDPSend {
public static void main(String[] args)throwsIOException {
//1,创建DatagramSocket对象
DatagramSocket sendSocket =new DatagramSocket();
//2,创建DatagramPacket对象,并封装数据
//public DatagramPacket(byte[]buf,intlength, InetAddress address,intport)
//构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号。
byte[ ] buffer ="hello,UDP".getBytes();
DatagramPacket dp =new DatagramPacket(buffer, buffer.length, InetAddress.getByName("192.168.75.58"), 12306);
//3,发送数据
//public void send(DatagramPacket p)从此套接字发送数据报包
sendSocket.send(dp);
//4,释放流资源
sendSocket.close();
}
}
UDP完成数据的接收
/*
* UDP接收端
*
* 1,创建DatagramSocket对象
* 2,创建DatagramPacket对象
* 3,接收数据存储到DatagramPacket对象中
* 4,获取DatagramPacket对象的内容
* 5,释放流资源
*/
publicclassUDPReceive {
public static void main (String[]args) throws IOException {
//1,创建DatagramSocket对象,并指定端口号
DatagramSocket receiveSocket = new DatagramSocket(12306);
//2,创建DatagramPacket对象,创建一个空的仓库
byte[ ] buffer=new byte[1024];
DatagramPacket dp = new DatagramPacket (buffer, 1024);
//3,接收数据存储到DatagramPacket对象中
receiveSocket.receive(dp);
//4,获取DatagramPacket对象的内容
//谁发来的数据getAddress()
InetAddress ipAddress=dp.getAddress();
String ip = ipAddress.getHostAddress();//获取到了IP地址
//发来了什么数据getData()
byte[ ] data=dp.getData();
//发来了多少数据getLenth()
int length = dp.getLength();
//显示收到的数据
String dataStr = new String(data,0,length);
System.out.println("IP地址:"+ip+"数据是"+dataStr);
//5,释放流资源
receiveSocket.close();
}
}
TCP通信
要实现TCP通信需要创建一个服务器端程序和一个客户端程序,为了保证数据传输的安全性,首先需要实现服务器端程序。
文件上传案例:
目前大多数服务器都会提供文件上传的功能,由于文件上传需要数据的安全性和完整性,很明显需要使用TCP协议来实现。接下来通过一个案例来实现图片上传的功能。如下图所示。原图:文件上传.bmp
文件上传案例多线程版本:
实现服务器端可以同时接收多个客户端上传的文件。
l我们要修改服务器端代码
网友评论