您的位置: 首页 - 站长

seo网站制作优化创世网站建设 优帮云

当前位置: 首页 > news >正文

seo网站制作优化,创世网站建设 优帮云,wordpress好用的主题,快速建设网站视频目录 Socket TCP和UDP区别 UDP#xff1a;无连接#xff0c;不可靠传输#xff0c;面向数据报#xff0c;全双工 TCP#xff1a;有连接#xff0c;可靠传输#xff0c;面向字节流#xff0c;全双工 无连接和有连接 可靠传输和不可靠传输
面向数据报和面向字节流…目录 Socket TCP和UDP区别 UDP无连接不可靠传输面向数据报全双工 TCP有连接可靠传输面向字节流全双工 无连接和有连接 可靠传输和不可靠传输  面向数据报和面向字节流  全双工和半双工 Java中对于传输层的一些API  DatagramSocket  DatagramSocket构造方法  send和receive方法 close()方法  DatagramPacket  DatagramPacket构造方法 实现一个UDP客户端-服务端的代码  明确服务端做的事 UDP服务端代码编写  明确客户端做的事  UDP客户端代码编写  通信结果  为什么客户端不需要指定一个特定的端口号呢  Socket 我们都知道用户在进行网络通信的时候应用层会将报文发送给传输层发送的这个过程应用层需要调用操作系统的一些api准确来说就是调用传输层的api应用层和传输层之间沟通调用的api就是Socket。严格意义上讲socket的api属于传输层。 TCP和UDP就是Socke的apit提供的两种不同的风格。 TCP和UDP区别 UDP无连接不可靠传输面向数据报全双工 TCP有连接可靠传输面向字节流全双工 无连接和有连接 无连接不确保接收方是否接收到信息。比如发短信发微信都是无连接通信不需要对方在线什么的就能直接把要传递的信息发送出去 有连接确保接收方会收到信息 。比如打电话打视频需要对方接起才能让双方进行信息的传递 原因UDP协议当中发送方和接收方的运输层进程之间没有建立握手只负责把应用层的报文打包成UDP报文段进行发送不关注接收方是否能收到所以UDP协议是无连接的。而TCP协议在传输数据之前会进行“三次握手”来确保接收方是能够收到信息的所以TCP协议是有连接的 可靠传输和不可靠传输  可靠传输就是发送方发送完信息后接收方如果收到了信息发送方可以知晓接收方已经收到了信息比如有些聊天的已读功能。 不可靠传输就是发送方发送完信息后不知道接收方是否收到了信息比如微信聊天发送方并不知道接收方是否接受到信息。 面向数据报和面向字节流  UDP协议就是面向数据报的协议。 传输层协议是以数据报为基本单位进行传输的操作系统不会对消息进行拆分也就是直接把应用层传过来的报文打包为UDP数据段然后传输到网络层  而TCP协议是面向字节流的协议。 TCP把数据看成一个没有结构的但是有序的字节流。 当使用TCP协议进行传输的时候一条应用层消息可能会被操作系统分成多个TCP报文。也就是说应用层发送过来的报文会被拆分成多个数据段比如| 应用层打算发送Hello This is Java,使用TCP协议就有可能拆分成两个TCP段 也有可能只有一个TCP段。 而对于UDP协议是不会拆分的 全双工和半双工 全双工一个通信通道可以双向传输既可以发送又可以接收 比如很多道路都是可以双向通行的 半双工通信通道只能单向传输只能发送或接收 比如青藏铁路这样的只能单向通行。 Java中对于传输层的一些API  DatagramSocket  在操作系统中一切皆为文件。 使用DatagramSocket这个类可以创建socket对象操作系统中把这个socket当做一个文件来处理相当于文件描述符表上的某一项。  使用一个socket对象就可以和另外一个主机进行通信了如果要和多个主机进行通信可以创建多个socket对象。  DatagramSocket构造方法  DatagramSocket()   系统自动分配一个空闲的端口号 DatagramSocket(int port)   指定端口号将socket和对应的端口相关联。 send和receive方法 void send(DatagramPacket packet)  代表socket发送应用层报文的方式 void receive(DatagramPacket packet) 代表socket接收应用层报文的方式 需要发送/接收的DatagramPackett就是一个应用层报文。  close()方法  用于关闭文件描述符表项释放进程当中的文件描述符表项所占用的空间。 DatagramPacket  表示的是UDP当中传输的一个应用层报文  DatagramPacket构造方法 DatagramPacket(byte[] buf,int length)把buf数组作为地址DatagramPacket(byte[] buf,int offset,int length,SocketAddress)把buf数组作为地址并且指定了需要传输的目标主机IP和端口号 实现一个UDP客户端-服务端的代码  假设约定客户端是运行在用户手中的服务器是运行在我们程序员自己的电脑 。 明确服务端做的事 1、读取客户端的请求 2、根据请求计算响应 3、将响应返回给客户端  需要指定的属性DatagramSocket socketsocket对象 用来为客户端提供socket来接收应用层报文 构造方法当中初始化socket对象并且指定本机当中需要建立通信的端口号。  注意应用层和传输层建立连接的时候一定要指明socket端口号不然就会导致选用无参构造方法无法明确UDP和应用层的哪个端口建立联系从而无法通信。  UDP服务端代码编写  import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketAddress; import java.net.SocketException;public class UdpEchoServer2 {//与服务端建立联系的socketprivate DatagramSocket datagramSocket;//使用构造方法并传入端口(关联端口)public UdpEchoServer2(int port) throws SocketException {//创建对象datagramSocketnew DatagramSocket(port);//port是服务端进程端口号}//创建start方法作为服务器启动public void start() throws IOException {System.out.println(服务器启动);while(true){//1、packet存放接收应用层内容DatagramPacket receivePacketnew DatagramPacket(new byte[4096],4096);//2、使用socket来接收应用层信息并将其存放在packet的byte数组中datagramSocket.receive(receivePacket);//3、截取byte数组中应用层信息的实际长度的内容比如hello就截取hello长度的内容//也就是获取数据报的实际长度部分String request new String(receivePacket.getData(),0,receivePacket.getLength());//4、模拟回显服务器将提取出来的数据报传给process进行处理并把响应赋值给responseString response process(request);//5、将响应字符串转化为字节数组byte[] responseByteresponse.getBytes();//6、获取响应数组长度int responseByteLength responseByte.length;//7、获取对应的客户端的IP和端口号SocketAddress根据packet的信息获取对应的地址SocketAddress address receivePacket.getSocketAddress();//8、构造返回给客户端的socket对象DatagramPacket responsePacketnew DatagramPacket(responseByte,responseByteLength,address);//9、使用构造的socket对象将响应发送给客户端datagramSocket.send(responsePacket);//输出处理结果作为验证System.out.println(客户端IP:receivePacket.getAddress()客户端端口号:receivePacket.getPort());}}//服务器响应public String process(String request){return udp服务器已响应request;}//服务端启动public static void main(String[] args) throws IOException {UdpEchoServer2 udpEchoServer2new UdpEchoServer2(9090);udpEchoServer2.start();}}启动服务端指定服务器端口号为9090此时启动后服务器正常启动但是由于客户端没有向服务端发送任何请求所以服务端会在receive方法出进行阻塞等待。 public static void main(String[] args) throws IOException {UdpEchoServer2 udpEchoServer2new UdpEchoServer2(9090);udpEchoServer2.start();} 明确客户端做的事  客户端主要做的事就是和服务端建立通信并且为服务端的receive方法内部的数据DatagramPacket等待服务端的send方法发送数据DatagramPacket回来并做出响应 UDP客户端代码编写  import java.io.IOException; import java.net.; import java.util.Scanner;public class UdpEchoClient {/** 客户端需要有的属性* 1、和服务端建立联系的socket* 2、服务端的ip地址* 3、服务端的端口号*/private DatagramSocket socket;//和服务端建立联系的socketprivate String serverIp;//服务端的ip地址(目的IP)private int serverPort;//服务端的端口号(目的端口//构造方法public UdpEchoClient(String serverIp,int serverPort) throws SocketException {socketnew DatagramSocket();this.serverIpserverIp;this.serverPortserverPort;}//启动客户端public void start() throws IOException {System.out.println(客户端已启动);Scanner inputnew Scanner(System.in);while(true){//1.用户从控制台输入想要发送给服务端的数据System.out.println(请输入您想要发送给服务端的数据);String request input.next();//2、构造Udp请求//将请求转为请求数组byte[] requestBytesrequest.getBytes();//获取请求数组的长度int length requestBytes.length;//3、指定服务端的ip和端口号DatagramPacket requestPacketnew DatagramPacket(requestBytes,length,InetAddress.getByName(serverIp),serverPort);//4、将请求发送到服务端的receive方法中socket.send(requestPacket);//5、读取并接收服务端的响应结果DatagramPacket responsePacketnew DatagramPacket(new byte[4096],4096);//存放读取的结果//接收服务端的响应socket.receive(responsePacket);//6、构造响应的字符串String responsenew String(responsePacket.getData(),0,responsePacket.getLength());//7、输出响应的字符串System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient udpEchoClientnew UdpEchoClient(127.0.0.1,9090);udpEchoClient.start();//客户端启动}}先启动服务端再启动客户端否则无法顺利完成通信。 通信结果  客户端和服务端通信的流程图解 为什么客户端不需要指定一个特定的端口号呢  首先客户端指定特定的端口号如果该端口号被占用那么就无法取得和服务端的通信了会抛出BindException异常。其次客户端是不可控的因为客户端往往是有很多台的不同客户端的程序运行情况我们是不知道的无法有效的进行控制这些不受到我们程序员的控制所以不如让客户端自由分配一个可以使用的端口号即可而服务端是可控的程序员可以手动的控制服务端的端口占用情况是非常方便的如果是随机分配的反而会提高程序员的工作难度。