我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何利用NIO建立Socket服务器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何利用NIO建立Socket服务器

本篇内容介绍了“如何利用NIO建立Socket服务器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

传统的Java 的IO,利用Socket建立服务器,接收客户端连接,一般都是为每一个连接建立一个线程,如果连接数巨大,那么服务器开销也将巨大。。NIO的原理,可以参照图:

如何利用NIO建立Socket服务器

Socket的Channel在Selector上注册某一种动作,Selector通过select操作,监视所有在该Selector注册过的Channel的对应的动作,如果监测到某一对应的动作,则返回selectedKeys,自己手动取到各个SelectionKey进行相应的处理。当然NIO不仅可以接受Socket的Channel,还有文件操作等其他IO操作。

作业的要求:

使用socket编程实现一个简单的文件服务器。客户端程序实现put功能(将一个文件从本地传到文件服务器)和get功能(从文件服务器取一远程文件存为本地文件)。客户端和文件服务器不在同一台机器上。

put [-h hostname] [-p portname] local_filename remote_filenameget [-h hostname] [-p portname] remote_filename local_filename

服务器端不使用nio,直接使用io的socket代码如下:

import java.io.*; import java.net.ServerSocket; import java.net.Socket;  public class ServerMain {          public static void main(String[] args) {          class SocketThread extends Thread{                          private Socket socket;             private byte[] buf;             private int len = 0;             public SocketThread(Socket socket) {                  this.socket = socket;                 buf = new byte[1024];             }              @Override             public void run() {                 try {                        DataInputStream dis = new DataInputStream(socket.getInputStream());                     DataOutputStream dos = new DataOutputStream(socket.getOutputStream());                                           //String command = dis.readUTF();                      len = dis.read(buf);                     String command = new String(buf,0,len);                                          System.out.println("command=="+command);                                          String[] temp =command.split(" ");                     command = temp[0];  //命令  是put还是get                     String filename = temp[1];  //文件名                                          File file = new File("C:\\",filename);//假设放在C盘                     if(command.equals("get")){                         if(!file.exists()){                             //dos.writeUTF("notexists");                             dos.write("notexists".getBytes());                             dos.flush();                             System.out.println("没有这个文件,无法提供下载!");                             dis.close();                             dos.close();                             socket.close();                             return;                         }                         //dos.writeUTF("DownloadReady "+file.length());                          dos.write("准备下载".getBytes());                         dos.flush();                                                  System.out.println("正在接受文件下载...");                         DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));                             while ((len = fis.read(buf))!= -1) {                              dos.write(buf, 0, len);                         }                         dos.flush();                                                  fis.close();                              System.out.println("文件传输完成");                     }                     else {                          //dos.writeUTF("UploadReady");                          dos.write("UploadReady".getBytes());                         dos.flush();                                                  System.out.println("正在接受文件上传...");                         DataOutputStream fileOut =                              new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));                           while ((len = dis.read(buf))!=-1) {                                fileOut.write(buf, 0, len);                         }                         System.out.println("上传完毕!");                         fileOut.close();                      }                     dis.close();                     dos.close();                     socket.close();                  } catch (Exception e) {                     e.printStackTrace();                 }             }                      }                  System.out.println("等待客户端连接....");         int index = 0;         try {             ServerSocket server = new ServerSocket(9527,300); //端口号9527  允许***连接数300             while (true) {                 Socket socket = server.accept();                 System.out.println("收到第"+(++index)+"个连接");                 new SocketThread(socket).start(); //对每个连接创建一个线程             }         } catch (Exception e) {             e.printStackTrace();         }     } }

使用NIO建立的Socket服务器,代码如下:

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer;  import java.nio.CharBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.util.Iterator;  public class NewSocketServer {       private static final int port = 9527;     private Selector selector;     private ByteBuffer clientBuffer = ByteBuffer.allocate(1024);       private CharsetDecoder decoder = Charset.forName("GB2312").newDecoder();     private CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();      //编码解码格式设置成GBK也行.UTF-8不行,中文乱码  (前提都是客户端没有设置任何编码解码格式)          public void setListener() throws Exception{                  selector = Selector.open(); //打开选择器                     ServerSocketChannel server = ServerSocketChannel.open();  //定义一个 ServerSocketChannel通道         server.socket().bind(new InetSocketAddress(port));  //ServerSocketChannel绑定端口           server.configureBlocking(false);   //配置通道使用非阻塞模式         server.register(selector, SelectionKey.OP_ACCEPT); //该通道在selector上注册  接受连接的动作                  while(true)         {                 selector.select();   //select() 会阻塞,直到在该selector上注册的channel有对应的消息读入             Iterator iter = selector.selectedKeys().iterator();                while (iter.hasNext()) {                     SelectionKey key = (SelectionKey) iter.next();                    iter.remove();  // 删除此消息                  process(key);   // 当前线程内处理。(为了高效,一般会在另一个线程中处理此消息)             }            }        }           private void process(SelectionKey key) throws IOException {                if (key.isAcceptable()) { // 接收请求                    ServerSocketChannel server = (ServerSocketChannel) key.channel();                    SocketChannel channel = server.accept();//类似于io的socket,ServerSocketChannel的accept函数返回 SocketChannel                 channel.configureBlocking(false);   //设置非阻塞模式                    SelectionKey sKey = channel.register(selector, SelectionKey.OP_READ);                  sKey.attach("read_command"); //这儿接收到连接请求之后可以为每个连接设置一个ID             }              else if (key.isReadable()) { // 读信息                     SocketChannel channel = (SocketChannel) key.channel();                    String name = (String) key.attachment();                  if(name.equals("read_command")){                     int count = channel.read(clientBuffer);                      if (count > 0) {                            clientBuffer.flip();                            CharBuffer charBuffer = decoder.decode(clientBuffer);                            String command = charBuffer.toString();                                                     //command形如:get abc.png 或者  put aaa.png                         System.out.println("command===="+command);  //得到客户端传来的命令                                                   String[] temp =command.split(" ");                         command = temp[0];  //命令  是put还是get                         String filename = temp[1];  //文件名                                                  SelectionKey sKey = channel.register(selector,SelectionKey.OP_WRITE);                            if(command.equals("put"))sKey.attach("UploadReady#"+filename);  //要保护该通道的文件名                         else if(command.equals("get")){                              if(!new File("C:\\",filename).exists()){ //假设文件都是在C盘根目录                                 System.out.println("没有这个文件,无法提供下载!");                                 sKey.attach("notexists");                              }                             else sKey.attach("DownloadReady#"+filename); //要保护该通道的文件名                         }                     } else {                            channel.close();                        }                    }                 else if(name.startsWith("read_file")){//这儿可以新开一个线程     文件操作也可以用NIO                      DataOutputStream fileOut =                          new DataOutputStream(                                 new BufferedOutputStream(                                         new FileOutputStream(                                                 new File("C:\\",name.split("#")[1]))));                       int passlen = channel.read(clientBuffer);                       while (passlen>=0) {                            clientBuffer.flip();                           fileOut.write(clientBuffer.array(), 0, passlen);                          passlen = channel.read(clientBuffer);                     }                     System.out.println("上传完毕!");                     fileOut.close();                      channel.close();                 }                 clientBuffer.clear();                }              else if (key.isWritable()) { // 写事件                    SocketChannel channel = (SocketChannel) key.channel();                    String flag = (String) key.attachment();                     if(flag.startsWith("downloading")){//这儿可以新开一个线程   文件操作也可以用NIO                     DataInputStream fis = new DataInputStream(                             new BufferedInputStream(                                     new FileInputStream(                                             new File("C:\\",flag.split("#")[1]))));                                            byte[] buf = new byte[1024];                     int len =0;                      while ((len = fis.read(buf))!= -1) {                          channel.write(ByteBuffer.wrap(buf, 0, len));                       }                       fis.close();                          System.out.println("文件传输完成");                     channel.close();                 }                 else if(flag.equals("notexists")){                      //channel.write(encoder.encode(CharBuffer.wrap(flag)));                        channel.write(ByteBuffer.wrap(flag.getBytes())); //不用编码也行    客户端直接接收    中文也不是乱码                     channel.close();                 }                 else if(flag.startsWith("UploadReady")){                      channel.write(encoder.encode(CharBuffer.wrap("UploadReady")));                                           //这儿如果不重新注册该通道的读操作    selector选择到该通道的将继续永远是写操作,也就无法跳转到上面的接受上传的处理                     SelectionKey sKey =channel.register(selector, SelectionKey.OP_READ);//register是覆盖的????!!!                     sKey.attach("read_file#"+flag.split("#")[1]);                     //key.attach("read_file#"+flag.split("#")[1]); //select不到读操作                 }                 else if(flag.startsWith("DownloadReady")){                      channel.write(ByteBuffer.wrap("准备下载".getBytes()));                      //channel.write(encoder.encode(CharBuffer.wrap("准备下载")));                        key.attach("downloading#"+flag.split("#")[1]);                 }              }           }             public static void main(String[] args) {                  try {              System.out.println("等待来至" + port + "端口的客户端连接.....");              new NewSocketServer().setListener();         } catch (Exception e) {             e.printStackTrace();         }      } }

客户端代码如下:

import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.util.Scanner;  public class ClientMain {      private   int ServerPort = 9527;     private   String ServerAddress = "192.168.1.154";     private   String GetOrPut = "get";        private   String local_filename = "";      private   String remote_filename  = "";      private   byte[] buf;     private   int len;     class SocketThread extends Thread{                  @Override         public void run() {              try {                                  File file = new File("C:\\",local_filename); //假设文件放在C盘                 if(!file.exists()&&GetOrPut.equals("put")){                      System.out.println("本地没有这个文件,无法上传!");                      return;                 }                                   InetAddress loalhost = InetAddress.getLocalHost();                 Socket socket = new Socket(ServerAddress,ServerPort,loalhost,44);                                             //服务器IP地址  端口号   本机IP 本机端口号                 DataInputStream dis = new DataInputStream(socket.getInputStream());                 DataOutputStream dos = new DataOutputStream(socket.getOutputStream());                                   //dos.writeUTF(GetOrPut+" "+remote_filename);//服务器端如果是io的socket,writeUTF和writeUTF对接                 dos.write((GetOrPut+" "+remote_filename).getBytes());                 dos.flush();                                 //String tempString = dis.writeUTF();                  buf = new byte[1024];                 len = dis.read(buf);                 String tempString = new String(buf,0,len);//服务器反馈的信息                                  //System.out.println(tempString);                  if(tempString.equals("notexists")){                     System.out.println("服务器没有这个文件,无法下载!");                      dos.close();                     dis.close();                     socket.close();                     return;                 }                                  if(tempString.startsWith("准备下载")){                       DataOutputStream fileOut =                          new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));                       while ((len = dis.read(buf))!=-1) {                            fileOut.write(buf, 0, len);                     }                     System.out.println("下载完毕!");                     fileOut.close();                     dos.close();                     dis.close();                     socket.close();                 }                 else if(tempString.equals("UploadReady")){                       System.out.println("正在上传文件.......");                     DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));                                             while ((len = fis.read(buf))!= -1) {                           dos.write(buf, 0, len);                     }                     dos.flush();                     System.out.println("上传完毕!");                     fis.close();                     dis.close();                     dos.close();                     socket.close();                 }                              } catch (Exception e) {                 e.printStackTrace();             }         }              }          public boolean checkCommand(String command)     {          if(!command.startsWith("put")&&!command.startsWith("get")){             System.out.println("输入命令错误");             return false;         }                  int index = -1;         String temp = "";         String[] tempStrings = null;                  if((index=command.indexOf("-h"))>0){             temp = command.substring(index+3);             temp = temp.substring(0, temp.indexOf(' '));             ServerAddress = temp;         }         if((index=command.indexOf("-p"))>0){             temp = command.substring(index+3);             temp = temp.substring(0, temp.indexOf(' '));             ServerPort = Integer.valueOf(temp);         }                  tempStrings = command.split(" ");         if(command.startsWith("put")){             GetOrPut = "put";             local_filename = tempStrings[tempStrings.length-2];             remote_filename = tempStrings[tempStrings.length-1];         }         else if(command.startsWith("get")){             GetOrPut = "get";             local_filename = tempStrings[tempStrings.length-1];             remote_filename = tempStrings[tempStrings.length-2];         }                  return true;     }          public static void main(String[] args) {         ClientMain thisC= new ClientMain();          Scanner sc = new Scanner(System.in);         String commandString = "";         do {             System.out.println("请输入命令:");              commandString = sc.nextLine();         } while (!thisC.checkCommand(commandString));                   ClientMain.SocketThread a = thisC.new SocketThread();         a.start();     } }

“如何利用NIO建立Socket服务器”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何利用NIO建立Socket服务器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何利用NIO建立Socket服务器

本篇内容介绍了“如何利用NIO建立Socket服务器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!传统的Java 的IO,利用Socket建
2023-06-17

python中socket是怎么建立服务器的

本篇内容介绍了“python中socket是怎么建立服务器的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!说明1、创建socket对象。2、
2023-06-20

如何建立云服务器

建立云服务器需要考虑以下步骤:确定云服务器的需求:首先需要确定云服务器的具体需求,包括存储大小、可扩展性、可用性和可靠性等方面,以确定需要采用的云服务商和云架构。选择云服务商:选择云服务商可以从多个角度考虑,例如价格、可用性、服务质量、技术支持以及安全性等等。在这一步,需要确保所选的云服务商具有足够的技术和服务能力,可以满足您的需求并提供可靠的服务。了解云计算基础架构:在选择云服务器之前,需要了解
2023-10-26

如何用云主机建立服务器

要用云主机建立服务器,你可以按照以下步骤进行操作:1. 选择云服务提供商:首先,你需要选择一个可靠的云服务提供商,每个云服务提供商都有自己的优势和特点,你可以根据自己的需求和预算进行选择。2. 注册账户和购买云主机:在选择好云服务提供商后,
2023-09-08

利用python socket管理服务器

一.socketserver的handle方法处理请求二.实例化socketserver的handle方法def funzioneDemo():    server = ThreadingServer((HOST,PORT),Handler
2023-01-31

如何建立云服务器网络

建立云服务器网络需要使用Web服务提供商提供的云服务器。以下是一些步骤:确定您要使用的云服务提供商的名称,并确保他们是经过认证的,可以提供安全的云托管环境。例如,您可以使用AWS和Azure。下载并安装最新版本的AWS和Azure。在您的云服务器上创建一个Web应用程序,并配置它的IP地址和端口号。使用云服务器来加载WordPress网站,并使用Azure服务提供的API来管理AWS和
2023-10-26

如何建立云服务器端口

建立云服务器端口有几个简单的步骤:确定您的云计算平台的操作系统类型和版本:如果您的云平台是基于Windows的,请确保云服务器平台的操作系统版本和操作系统版本匹配。如果您的云计算平台是基于Linux或MacOS的,则您需要考虑操作系统的兼容性。确定您要连接的云服务器主机数量:请确保云服务器提供商能够为您提供足够的服务器数量,因为您需要为每个主机创建一个云服务器端口,以便您可以使用多个主机。
2023-10-26

如何建立云服务器账号

建立云服务器账号是一个相对复杂的过程,需要遵循以下步骤:注册您的云服务器供应商账户并登录您的网站:首先,确认您已成功注册供应商的账户,并登录到您的云服务器账户。输入用户名和密码:确保您的账户密码是正确的,并且没有使用过相同的用户名和密码。用户名通常可以从您的云服务器供应商网站上下载。选择云服务器类型:您可以选择使用Amazon的云服务器,如GCP等。此外,您也可以选择使用其他服务,如AW
2023-10-26

如何建立云服务器连接

建立云服务器连接建立云服务器连接涉及选择服务提供商、创建实例、进行连接、设置安全措施、管理服务器和访问数据。遵循这些步骤来安全访问和管理您的云服务器。考虑网络连接选项、数据备份、持续监控和利用支持资源以优化云体验。
如何建立云服务器连接
2024-04-09

如何建立云服务器连接

要建立云服务器连接,通常需要以下步骤:1. 选择云服务提供商:根据你的需求和预算选择一个可靠的云服务提供商。2. 注册并创建云服务器实例:在选定的云服务提供商网站上注册账号,并根据你的需求创建一个新的云服务器实例。你需要选择服务器的地理位置
2023-08-19

云服务器是如何建立的

云服务器的建立一般包括以下几个步骤:1. 选择云服务提供商:根据需求选择合适的云服务提供商。2. 注册账号:在选择的云服务提供商的官网上注册一个账号。3. 创建虚拟机实例:登录云服务提供商的管理控制台,选择创建虚拟机实例的选项。4. 选择实
2023-08-15

如何建立并登录云服务器

要建立并登录云服务器,需要按照以下步骤进行操作:1. 选择云服务提供商:选择一家可靠的云服务提供商。2. 注册账号:访问所选云服务提供商的官方网站,注册一个账号。3. 创建云服务器实例:登录到云服务提供商的控制台,选择创建云服务器实例的选项
2023-08-09

如何建立自己的云服务器

建立自己的云服务器可以帮助你快速构建和部署应用程序,以及实现资源的弹性伸缩和高可用性。以下是一些步骤可以帮助你建立自己的云服务器:确定你的需求:首先你需要明确你的应用程序需要哪些云服务器资源和功能,例如数据库、虚拟机、容器、存储、网络等。寻找供应商:寻找可靠的云服务器供应商,如AWS、Google、IBM等,并对其进行详细的评估。配置选项:在购买云服务器之前,你需要选择你所需要的云服务器
2023-10-26

如何使用BIND在Linux上建立DNS服务器

这篇文章主要介绍“如何使用BIND在Linux上建立DNS服务器”,在日常操作中,相信很多人在如何使用BIND在Linux上建立DNS服务器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用BIND在Li
2023-06-16

如何建立云服务器网络共享服务

建立云服务器网络共享服务可以遵循以下步骤:确定云服务器提供商的网络共享需求。可以在网站上查找相应的云服务器的服务条款,根据自己的需求选择不同的网络共享服务。在使用云服务器之前,需要安装相应的软件和软件包。软件可以是虚拟机或者云服务器客户端。将云服务器与您的其他计算机、存储设备、网络连接等设备连接起来,以便实现高效的数据共享。在使用云服务器之前,需要将您的网络带宽进行限制,可以使用WAN
2023-10-26

如何建立云服务器端口协议服务

建立云服务器端口协议服务是一个比较复杂的任务,需要考虑许多因素,包括服务提供商、网络服务提供商和应用程序编程接口(API)等因素。下面是一种简单的方法来创建一个端口协议服务:确定云服务器提供商:在开始创建云服务器端口协议服务之前,需要了解该服务提供商所提供的服务种类和服务的类型,例如是Windows、Linux或者是OpenStack等。选择适当的API:选择适当的API是创建端口协议服务
2023-10-26

如何建立云服务器网络链接

建立云服务器网络链接时,建议遵循以下步骤:确认要连接的云服务器名称和位置:确保云服务器与您的网络连接可靠且与您在其上创建的网站在同一个IP地址范围内。如果不在同一IP地址范围内,请在云服务器提供商的网站上查找其位置。创建HTTPS连接:为了确保云服务器网络链接的安全,您需要选择一种安全的HTTPS连接方式。选择HTTPS是因为它具有更高的安全性和可用性。检查您的连接到云服务器的IP地址:
2023-10-26

编程热搜

目录