国外好看的网站设计pageadmin 制作网站怎么绑定域名

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

国外好看的网站设计,pageadmin 制作网站怎么绑定域名,seo系统优化,做一个微网站平台文章目录 网络编程套接字UDP/TCP的api使用 网络编程套接字 socket#xff0c;是操作系统给应用程序#xff08;传输层给应用层#xff09;提供的api#xff0c;Java也对这个api进行了封装。 socket提供了两组不同的api#xff0c;UDP有一套#xff0c;TCP有一套#x… 文章目录 网络编程套接字UDP/TCP的api使用 网络编程套接字 socket是操作系统给应用程序传输层给应用层提供的apiJava也对这个api进行了封装。 socket提供了两组不同的apiUDP有一套TCP有一套本文主要介绍api的使用. 这里介绍TCP和UDP的区别: 连接:通信双方各自保存对方的信息,就是连接.两个通信实体之间建立的一条可靠的、有序的、双向的通信通道。 可靠传输和不可靠传输:可靠传输是发送方可以知道消息有没有被接收方收到 面向字节流:网络中传输的数据的基本单位是字节 面向数据报:每次传输的基本单位是数据报 全双工:一个信道可以双向通信,就像公路一样是双向车道 UDP/TCP的api使用 Java把系统原生的api进行了封装,操作系统中有一类文件叫做scoket文件,它抽象的表示了网卡这样的设备,通过操作scoket文件就可以对网卡进行操作. 通过网卡发送数据,就是写scoket文件. 通过网卡接收数据,就是读socket文件. UDP scoket api的使用 DatagramScoket是UDP scoket,用于接收和发送数据报. 核心的类有两个: 1.DatagramScoket DatagramScoket是UDP scoket,用于接收和发送数据报. DatagarmScoket的构造方法 方法说明DatagramSocket()创建一个UDP数据报套接字的Socket绑定到本机任意一个随机端口一般用于客户端DatagramSocket(int port)创建一个UDP数据报套接字的Socket绑定到本机指定的端口(port就是端口号) DatagramScoket方法 方法名说明void receive(DatagramPacket p)从此套接字接收数据报如果没有接收到数据报该方法会阻塞等待)void send(DatagramPacket p)从此套接字发送数据报包不会阻塞等待直接发送)void close()关闭数据报套接字 这里的DatagramPacket p是作为输出型参数的 小知识: 输出型参数:输出型参数是一个变量函数会修改它的值并将修改后的值传递回调用者。调用者可以通过这个参数获取函数处理后的数据。就像是我们自己带饭盒去食堂吃饭,饭盒就相当于DatagramPacket,打饭的阿姨会帮我们把饭盒装满饭菜,此时打饭的阿姨就是void receive. 2.DatagramPacket UDP面向数据报,每次发送接收数据的基本单位,就是一个UDP数据报. 构造方法: 方法说明DatagramPacket(byte[] buf, int length)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组buf中,接收指定的长度(length)DatagramPacket(byte[] buf,int offset,int length,SocketAddress address)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组buf中,接收指定的长度(length),address表示指定的目的主机的ip和端口号 常用方法: 方法说明InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址int getPort()从接收的数据报中,获取发送端主机的端口号,或者从发送的数据报中,获取接收端主机的端口号byte[] getData()获取数据报中的数据 利用上述的方法及概念我们实现一个回显服务器程序; package net;/* 服务器/import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socketnull;//服务器一般都是要自己指定端口号public UdpEchoServer(int port) throws SocketException {socketnew DatagramSocket(port);}public void start() throws IOException {//服务器需要不停的处理请求,所以我们这里用while循环while (true){//1.等待客户端发送请求,并用DatagramPacket保存,如果没有请求,就进入阻塞.DatagramPacket requstPacketnew DatagramPacket(new byte[4399],4399);socket.receive(requstPacket);//2.将收到的请求构造成字符串,便于后边做出响应的处理String requstnew String(requstPacket.getData(),0,requstPacket.getLength());//3.通过接收的数据,服务器做出响应,process就是具体做出响应的逻辑//这里的回显服务器我们直接返回客户端的输入即可,没什么深层次的逻辑String responseprocess(requst);//4.将响应后的数据报构造出并且发送//requstPacket.getSocketAddress()就是和服务器通信的对端的ip和端口.//这里就是把请求中的源ip和源端口,作为响应的目的ip和目的端口DatagramPacket resonsePacketnew DatagramPacket(response.getBytes(),response.getBytes().length,requstPacket.getSocketAddress());socket.send(resonsePacket);}}private String process(String requst) {return requst;}public static void main(String[] args) throws IOException {UdpEchoServer servernew UdpEchoServer(9090);server.start();} } / 客户端 / package net;import java.io.IOException; import java.net.; import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socketnull;//目标服务器的IP和端口private String serverIP;private int serverPOrt;//客户端一般可以使用系统随机分配的端口号public UdpEchoClient(String serverIP,int serverPOrt) throws SocketException {this.serverIPserverIP;this.serverPOrtserverPOrt;socketnew DatagramSocket();}public void start() throws IOException {Scanner scannernew Scanner(System.in);while (true){if (!scanner.hasNext()){break;}//将从控制台读取到的数据存入requstString requstscanner.next();//1.将requst构成数据报,并发送给服务器DatagramPacket requstPacketnew DatagramPacket(requst.getBytes(),requst.getBytes().length, InetAddress.getByName(serverIP),serverPOrt);socket.send(requstPacket);//2.等待服务器返回响应,构造数据报进行接收,并进行输出DatagramPacket responsePacketnew DatagramPacket(new byte[4399],4399);socket.receive(responsePacket);String responsenew String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {//127.0.0.1通用,代表本机端口号UdpEchoClient clientnew UdpEchoClient(127.0.0.1,9090);client.start();} } 代码分析: TCP socket api的使用 TCP是面向字节流的,传输的基本单位是字节. 连接建立:从客户端Socket的构造方法发送连接请求,服务器的SerevrSocket监听到请求后并且调用accept()方法,这样就建立了连接,然后accept()方法在服务器中会生成一个新的Socket对象用来进行通信. api介绍: ServerSocket 构造方法: 方法签名说明ServerSocket(int port)创建⼀个服务端流套接字Socket并绑定到指定端⼝ 方法: 方法说明Socket accept()开始监听指定端⼝创建时绑定的端⼝有客⼾端连接后,返回一个Socket对象,并且基于Socket建立与客户端的连接,没有就阻塞等待void close()关闭套接字 Socket 构造方法: 方法说明Socket(String host, int port)创建⼀个客⼾端流套接字Socket并与对应IP的主机上,对应端口的进程建立连接 方法: 方法说明InetAddress getInetAddress()返回套接字锁连接的地址InputStream getInputStream()返回此套接字的输⼊流OutputStream getOutputStream()返回此套接字的输出流 ServerSocket只能在服务器中使用,而Socket既可以在服务器中使用也可以在客户端使用. TCP是有连接的,就类似需要客户端拨打电话,服务器来接听. 接下来我们用回显服务器案例来介绍TCP的api的使用以及是如何通信的. 首先我们编写一下服务器程序. private ServerSocket requstSocketnull;public TcpEchoServer(int port) throws IOException {requstSocketnew ServerSocket(port);}通过ServerSocket提供的构造方法,给服务器分配一个端口号(这里我们需要注意,服务器是必须要指定端口号的,而客户端系统自己分配端口号就可以) 服务器的ServerSocket是用来监听请求的,如果有客户端发送请求,那么ServerSocket就会感知到 服务器: public void start() throws IOException {/当ServerSocket监听到有客户端发来请求后,会调用accept()方法一旦连接建立,accept()方法就会返回一个新的Socket对象,这个Socket就是专门用来与该客户端进行通信的/Socket clientSocketrequstSocket.accept();//把处理请求和返回相应的逻辑这里我们放到这个方法中来实现processConntion(clientSocket);}当ServerSocket监测到有客户端发来连接的请求,ServerSocket会调用accept()方法,accept()方法会返回一个新的Socket对象,这就算是建立了连接而这个新的对象就是用来与客户端通信 上述过程就像是客户端的Socket想要通过服务器的ServerSocket认识服务器中的Socket.于是客户端的Socket就请求服务器的ServerSocket帮忙牵个线,搭个桥.服务器的ServerSocket就把服务器的Socket的电话号码给了客户端,而客户端的构造方法就类似于给服务器拨通了电话,而当前只是在响铃,而accept()方法就类似接听,只有调用accept()的方法后才算真正建立连接 private void processConntion(Socket clientSocket) {try(InputStream inputStreamclientSocket.getInputStream();OutputStream outputStreamclientSocket.getOutputStream()){Scanner scannernew Scanner(inputStream);while (true){if (!scanner.hasNext()){break;}String requstscanner.next();String responseprocess(requst);PrintWriter printWriternew PrintWriter(outputStream);printWriter.println(response);printWriter.flush();}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String requst) {return requst;}try(InputStream inputStreamclientSocket.getInputStream();OutputStream outputStreamclientSocket.getOutputStream())InputStream inputStreamclientSocket.getInputStream();就是从网卡内读数据 OutputStream outputStreamclientSocket.getOutputStream()就是往网卡内写数据 TCP中操作socket文件,对其进行读写(InputStream,OutputStream),就是在操作网卡,操作系统把网卡抽象成了一个文件.就像看电视,我们只需要操作遥控器即可,而不需要直接去电视脸上操作 客户端 public TcpEchoClient(String serverIP,int serverPort) throws IOException {socketnew Socket(serverIP,serverPort);}执行上述代码就会和对应的服务器进行tcp的连接建立流程(在系统内核中) 内核走完流程,服务器这边就会从accept()返回,于是就可以通信了. public void start() throws IOException {try (InputStream inputStreamsocket.getInputStream();OutputStream outputStreamsocket.getOutputStream()){Scanner scannerConslenew Scanner(System.in);Scanner scannernetWorknew Scanner(inputStream);while (true){if (!scannerConsle.hasNext()){break;}String requstscannerConsle.next();PrintWriter printWriternew PrintWriter(outputStream);printWriter.println(requst);printWriter.flush();String responsescannernetWork.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}finally {socket.close();}}Scanner scannerConslenew Scanner(System.in);Scanner scannernetWorknew Scanner(inputStream);在客户端上,scannerConsle是在控制台中读取数据,也就是我们用户输入的时候读取数据,并且转变为String 发送给服务器(就是通过OutputStream写入操作网卡的文件). 而scannernetWork就是在服务器做出响应后,通过inputStream读取网卡上的数据 最终打印出结果. PrintWriter PrintWriter 是 Java 中的一个类位于 java.io 包中用于以文本形式写入输出数据。它继承了 Writer 抽象类提供了多种方法来方便地写入字符和字符串到文件或其他输出流中. printWriter.flush();这个方法的作用是刷新缓冲区.因为IO都是比较低效的操作,一次一次读写,太麻烦.缓冲区就将先把数据放到内存缓冲区中,等攒够了数据一起发送,这样就变得高效了,而printWriter.flush();就是将缓存区刷新,将数据一点一点发送出去,不用等到满了一股脑发出去. 在客户端运行完毕之后我们要cloose() socket.close();TCP服务器客户端执行流程 上述客户端代码还存在一个问题: 如果有多个客户端发送连接请求,我们就会发现第一个客户端连接上服务器之后,服务器会从accept这里返回,进入具体处理请求的processConntion方法,接下来在具体处理请求方法的内部scanner.hasNext()处阻塞,等待客户端发送请求,此时如果有客户端发送请求,hasNextt继续向下执行,构造String,计算响应.返回响应给客户端.执行完上述操作后继续循环,等待客户端发送请求. 上面这种情况,如果是很多个客户端一起执行,即使其他客户端在内核已经建立了连接,但是由于服务器一直在processConntion方法中为第一个发送请求的客户端服务,一直在processConntion方法循环处理请求,所以其他的客户端无法执行到accept()方法,只是在内核建立连接,没有调用accept方法就不能算真正意义上的连接.其他的客户端也就无法执行. 针对上述问题我们如何改进? 就要用到我们之前学到的多线程,一个线程处理连接,另一个线程处理请求返回响应的逻辑. 但是如果有很多客户端,每次发送请求的时候都要创建一个新的线程,处理完成后销毁,对于系统资源的开销是比较大的,所以我们这里使用线程池. 完整代码展示: /* 服务器 / package net;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class TcpEchoServer {private ServerSocket socketnull;public TcpEchoServer(int port) throws IOException {socketnew ServerSocket(port);}public void start() throws IOException {ExecutorService pool Executors.newCachedThreadPool();while (true){Socket cilentSocket socket.accept();pool.submit(new Runnable() {Overridepublic void run() {processConnetion(cilentSocket);}});}}private void processConnetion(Socket cilentSocket) {try (InputStream inputStreamcilentSocket.getInputStream();OutputStream outputStreamcilentSocket.getOutputStream()){Scanner scannernew Scanner(inputStream);while (true){if (!scanner.hasNext()){break;}String requstscanner.next();String responseprocess(requst);PrintWriter printWriternew PrintWriter(outputStream);printWriter.println(response);printWriter.flush();}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String requst) {return requst;}public static void main(String[] args) throws IOException {TcpEchoServer servernew TcpEchoServer(9090);server.start();} } / 客户端 */ package net;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner;public class TcpEchoClient {private Socket socketnull;public TcpEchoClient(String serverIP,int serverPort) throws IOException {socketnew Socket(serverIP,serverPort);}public void start() throws IOException {try (InputStream inputStreamsocket.getInputStream();OutputStream outputStreamsocket.getOutputStream()){Scanner scannerConnew Scanner(System.in);Scanner scannerNetnew Scanner(inputStream);while (true){if (!scannerCon.hasNext()){break;}String requstscannerCon.next();PrintWriter printWriternew PrintWriter(outputStream);printWriter.println(requst);printWriter.flush();String responsescannerNet.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}finally {socket.close();}}public static void main(String[] args) throws IOException {TcpEchoClient clientnew TcpEchoClient(127.0.0.1,9090);client.start();}}