网络编程Socket
Posted breezezqf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程Socket相关的知识,希望对你有一定的参考价值。
网络通信协议
网络通信协议有很多种,目前应用最广泛的是TCP/IP协议(传输控制协议/英特网互联协议),它是一个包括TCP协议和IP协议,UDP协议和其它一些协议的协议组,在学习具体协议之前首先了解一下TCP/IP协议组的层次结构。
在进行数据传输时,要求发送的数据与收到的数据完全一样,这是,就需要在原有的数据上添加很多信息,以保证数据在传输过程中数据格式完全一致。TCP/IP协议的层次结构比较简单,共分四层
应用层----如HTTP,FTP,DNS
主要负责应用程序的协议,例如HTPP,FTP协议等。
传输层----如TCP,UDP
主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议。
网络层----如IP,ICMP,IGMP
网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送道目标计算机或网络。
链路层----如驱动程序,接口
链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光驱,网线提供的驱动
地址和端口号
要想使网络中的计算机能够进行通信,必须为每台计算机指定一个标识符,通过这个标识号来接受数据的计算机或发送数据的计算机。
在TCP/IT协议中,这个标识号就是IP地址,它可以唯一标识一台计算机,目前IP地址广泛使用的是IPv4,它是由4个字节大小的二进制数来表示,由于二进制形式表示的IP地址非常不便于记忆和处理,因此通常会将IP地址写成十进制的形式,每个字节用一个十进制数字(0-255)表示,数字间用符号“.”分开,如192.168.1.129
随着计算机网络规模的不断扩大,对IP地址的需求也越来越多,IPV4这种用4个字节表示的IP地址面临枯竭,因此IPv6 便应运而生了,IPv6使用16个字节表示IP地址,它所拥有的地址容量约是IPv4的8×1028倍,达到2128个(算上全零的),这样就解决了网络地址资源数量不够的问题。
通过IP地址可以连接到指定计算机,但如果想访问目标计算机中的某个应用程序,还需要指定端口号。在计算机中,不同的应用程序是通过端口号区分的。端口号是用两个字节(16位的二进制数)表示的,它的取值范围是0~65535,其中,0~1023之间的端口号用于一些知名的网络服务和应用,用户的普通应用程序需要使用1024以上的端口号,从而避免端口号被另外一个应用或服务所占用。
InetAddress
JDK中有个InetAdderss类,该类用于封装一个IP地址,并提供了一系列与IP地址相关的方法
UDP协议
udp是无限连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。
TCP协议
TCP协议是面向连接的通信协议,即在传输数据前先在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。第一次握手,客户端向服务器端发出连接请求,等待服务器确认,第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求,第三次握手,客户端再次向服务器端发送确认信息,确认连接。整个交互过程如下图所示。
由于TCP协议的面向连接特性,它可以保证传输数据的安全性,所以是一个被广泛采用的协议,例如在下载文件时,如果数据接收不完整,将会导致文件数据丢失而不能被打开,因此,下载文件时必须采用TCP协议。
TCP协议
TCP通信同UDP通信一样,都能实现两台计算机之间的通信,通信的两端都需要创建socket对象。
区别在于,UDP中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地发送数据。
而TCP通信是严格区分客户端与服务器端的,在通信时,必须先由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端,并且服务器端程序需要事先启动,等待客户端的连接。
在JDK中提供了两个类用于实现TCP程序,一个是ServerSocket类,用于表示服务器端,一个是Socket类,用于表示客户端。
通信时,首先创建代表服务器端的ServerSocket对象,该对象相当于开启一个服务,并等待客户端的连接,然后创建代表客户端的Socket对象向服务器端发出连接请求,服务器端响应请求,两者建立连接开始通信。
ServerSocket
使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上(参数port就是端口号)。
ServerSocket(int port) 创建绑定到特定端口的服务器套接字
常用方法
accept() 侦听并接收到此套接字的连接
getInetAddress() 返回此服务器套接字的本地地址
ServerSocket对象负责监听某台计算机的某个端口号,在创建ServerSocket对象后,需要继续调用该对象的accept()方法,接收来自客户端的请求。当执行了 accept()方法之后,服务器端程序会发生阻塞,直到客户端发出连接请求,accept()方法才会返回一个Scoket对象用于和客户端实现通信,程序才能继续向下执行。
Socket
ServerSocket对象可以实现服务端程序,但只实现服务器端程序还不能完成通信,此时还需要一个客户端程序与之交互,为此JDK提供了一个Socket类,用于实现TCP客户端程序。
Soclet(String host,int port) 创建一个流套接字并将其连接到指定主机上的指定端口号
使用该构造方法在创建Socket对象时,会根据参数去连接在指定地址和端口上运行的服务器程序,其中参数host接收的是一个字符串类型的IP地址
Socket(InetAddress address,int port) 创建一个流套接字并将其连接到指定IP地址的指定端口号
该方法在使用上与第二个构造方法类似,参数address用于接收一个InetAddress类型的对象,该对象用于封装一个IP地址。
常用方法
方法声明 |
功能描述 |
int getPort() |
该方法返回一个int类型对象,该对象是Socket对象与服务器端连接的端口号 |
InetAddress getLocalAddress() |
该方法用于获取Socket对象绑定的本地IP地址,并将IP地址封装成InetAddress类型的对象返回 |
void close() |
该方法用于关闭Socket连接,结束本次通信。在关闭socket之前,应将与socket相关的所有的输入/输出流全部关闭,这是因为一个良好的程序应该在执行完毕时释放所有的资源 |
InputStream getInputStream() |
该方法返回一个InputStream类型的输入流对象,如果该对象是由服务器端的Socket返回,就用于读取客户端发送的数据,反之,用于读取服务器端发送的数据 |
OutputStream getOutputStream() |
该方法返回一个OutputStream类型的输出流对象,如果该对象是由服务器端的Socket返回,就用于向客户端发送数据,反之,用于向服务器端发送数据 |
在Socket类的常用方法中,getInputStream()和getOutStream()方法分别用于获取输入流和输出流。当客户端和服务端建立连接后,数据是以IO流的形式进行交互的,从而实现通信。
简单的TCP网络程序
1 public class UDPReceive { 2 public static void main(String[] args) throws Exception { 3 //1,创建DatagramSocket对象,并指定端口号 4 DatagramSocket receiveSocket=new DatagramSocket(12306); 5 //2,创建DatagramPacket对象,创建一个空的仓库。 6 byte[] b=new byte[1024]; 7 DatagramPacket dp=new DatagramPacket(b, b.length); 8 //3,接收数据存储到DatagramPacket对象中 9 receiveSocket.receive(dp); 10 //4,获取DatagramPacket对象的内容 11 //谁发来的数据 getAddress() 12 InetAddress ipAddress = dp.getAddress(); 13 String ip = ipAddress.getHostAddress();//获取到了IP地址 14 //发来了什么数据 getData() 15 byte[] data = dp.getData(); 16 //发来了多少数据 getLenth() 17 int length = dp.getLength(); 18 //显示收到的数据 19 String dataStr = new String(data,0,length); 20 System.out.println("IP地址:"+ip+ "数据是"+ dataStr); 21 //5,释放流资源 22 receiveSocket.close(); 23 24 25 } 26 }
1 /** 2 * 发送端 3 * @author breeze 4 * 5 */ 6 public class UDPSend { 7 public static void main(String[] args) throws Exception { 8 //1,创建DatagramSocket对象 9 DatagramSocket sendScoket=new DatagramSocket(); 10 //2,创建DatagramPacket对象,并封装数据 11 byte[] b="Hello World".getBytes(); 12 DatagramPacket dp=new DatagramPacket(b, b.length,InetAddress.getByName("192.168.1.236"),12306); 13 //3,发送数据 14 sendScoket.send(dp); 15 //4,释放流资源 16 sendScoket.close(); 17 }
总结
IP地址:用来唯一表示我们自己的电脑的,是一个网络标示
端口号: 用来区别当前电脑中的应用程序的
UDP: 传送速度快,但是容易丢数据,如视频聊天,语音聊天
TCP: 传送稳定,不会丢失数据,如文件的上传、下载
UDP程序交互的流程
发送端
1,创建DatagramSocket对象
2,创建DatagramPacket对象,并封装数据
3,发送数据
4,释放流资源
接收端
1,创建DatagramSocket对象
2,创建DatagramPacket对象
3,接收数据存储到DatagramPacket对象中
4,获取DatagramPacket对象的内容
5,释放流资源
TCP程序交互的流程
客户端
1,创建客户端的Socket对象
2,获取Socket的输出流对象
3,写数据给服务器
4,获取Socket的输入流对象
5,使用输入流,读反馈信息
6,关闭流资源
服务器端
1,创建服务器端ServerSocket对象,指定服务器端端口号
2,开启服务器,等待着客户端Socket对象的连接,如有客户端连接,返回客户端的Socket对象
3,通过客户端的Socket对象,获取客户端的输入流,为了实现获取客户端发来的数据
4,通过客户端的输入流,获取流中的数据
5,通过客户端的Socket对象,获取客户端的输出流,为了实现给客户端反馈信息
6,通过客户端的输出流,写数据到流中
7,关闭流资源
以上是关于网络编程Socket的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装
VSCode自定义代码片段14——Vue的axios网络请求封装