热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

java实现简单网络象棋游戏

这篇文章主要为大家详细介绍了java实现简单网络象棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了java实现网络象棋游戏的具体代码,供大家参考,具体内容如下

游戏规则:

1.将/帅:不能出田字格,不能走斜线,只能前进后退向左向右,每次只走一格;

2.士/仕:不能出田字格,只能走斜线,每次只走一格;

3.象/相:只能走田字格,中间防止蹩脚,不能有棋;

4.马:只能走日,(这个比较麻烦,且看下图标识)

5.车:车只能走直线,这个很好理解,不细说了;

6.炮:

情况一:纯走路—->中间和目的地都不能有棋
情况二:吃棋—–>中间要有一颗棋,目标也有棋,且是敌方的棋,毕竟不能自己吃自己哈

7.卒/兵:

河这边:只能前进不能后退,不能横着走!!!
河对面:可以前进,可以横着走,不能后退!!!

面板设计

 

看上去一定很挫!哈哈,别急,听我细细道来!
一般的界面设计我们都知道横纵坐标是这样的: 

但是我选择背道而行,不是因为别的,是为了更好的去让初学者理解,我们把原本的x坐标看成数组的列(col),把y坐标看成我们数组的行(row),这样是不是更好理解一点呢,当然了我就是这么理解的,哈哈,接下来的游戏代码编程我们会把横坐标用y*width,纵坐标用x*height你们应该就能理解为什么了,因为x是数组的行,也就是坐标纵坐标(y)的体现,同理数组中的y也是如此。

数据传输:这里我们采用UDP协议来进行通讯,所以你们也要先去了解一下UDP协议的一些基本方法,这里就不细讲了。

通讯协议:这里我们自定义通讯协议啊:
“play|”——–以此开头代表一端发出了游戏邀请,等待另一端的回应;
“connect|”——-以此开头代表另一端收到邀请并且同意建立连接通讯!如果邀请者受到这条消息就代表通讯建立成功,可以开始游戏了;
“move|”——以此开头代表移动数据传输,如果一端移动了棋子,那么另一端也要收到信息,重新绘制界面;
“lose|”——–以此开头代表一方认输,如果有一方认输就会向另一方发送该信息;
“quit|”——-以此开头代表一方退出游戏,任意一方离开都会向对方发送该信息,以提示对方;
“success|”—–以此开头代表胜利,某一方胜利就向对方发出信息,通知对方;
“regret|”——以此开头表示悔棋,这个不用讲了吧,大家都明白,但是本次编程中我没有把这个加进去,这个你们可以自己根据自己需要去添加。
(肯定有人问我这个协议是谁定义的,啊哈哈,让你们失望了,这是我自己定义的,这个通讯协议只适用于你们写的这个代码,和使用这个代码的两个人通讯使用,所以协议如何自己可以定义的哦)

代码实现

1.Chess类:

package internet_chess;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.ImageObserver;

import javax.swing.JPanel;

public class Chess {
  public int Row = 12;
  public int Col = 11;
  public String chessName;//当前棋子对象的名字
  public int owner;//当前棋子对象的所有者--黑方还是红方
  public Point point;//当前棋子对象的位置
  public Image chessImage;//当前棋子对象的图像
  private int BLACKCHESS = 1;
  private int REDCHESS = 0;//红方0,黑方1
  private int width = 40;
  private int height = 40;

  public Chess(String name, int own,Point point)//获取每一个棋子对象名字,所有者,位置,和图片信息
  {
    this.chessName = name;
    this.owner = own;
    this.point = point;
    if(owner == BLACKCHESS)//如果所有者是黑方
    {
      if(chessName.equals("将"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/0.png");
      }
      else if(chessName.equals("士"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/1.png");
      }
      else if(chessName.equals("象"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/3.png");
      }
      else if(chessName.equals("马"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/5.png");
      }
      else if(chessName.equals("车"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/7.png");
      }
      else if(chessName.equals("炮"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/9.png");
      }
      else if(chessName.equals("卒"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/11.png");
      }
    }
    else//如果所有者是红方
    {
      if(chessName.equals("帅"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/16.png");
      }
      else if(chessName.equals("仕"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/17.png");
      }
      else if(chessName.equals("相"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/19.png");
      }
      else if(chessName.equals("马"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/21.png");
      }
      else if(chessName.equals("车"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/23.png");
      }
      else if(chessName.equals("炮"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/25.png");
      }
      else if(chessName.equals("兵"))
      {
        chessImage = Toolkit.getDefaultToolkit().getImage("F:/Image/chess/27.png");
      }
    }
  }

  protected void paint(Graphics g,JPanel i)//画棋子
  {
    g.drawImage(chessImage, point.y*width-width/2, point.x*height-height/2, width, height, (ImageObserver)i);
  }

  protected void paintSeclected(Graphics g)//画鼠标选择了以后的棋子对象的边框
  {
    g.drawRect(point.y*width-width/2, point.x*height-height/2, width, height);
  }

  public void SetPos(int x, int y)//重新设置移动以后的棋子对象的位置坐标
  {
    point.x = x;
    point.y = y;
  }

  public void ReversePos()//将该对象的位置坐标逆置输出,用于方便显示信息情况
  {
    point.x = Row-1 - point.x;
    point.y = Col-1 - point.y;
  }
}

2.ChessPanel类:

package internet_chess;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class ChessPanel extends JPanel implements Runnable{
  private int BLACKCHESS = 1;
  private int REDCHESS = 0;//黑棋是1,红旗是0
  public Chess chess[] = new Chess[32];//创建了32个棋子对象
  private int width = 40;
  private int height = 40;
  public int Row = 12;
  public int Col = 11;//11行10列
  public int map[][] = new int [Row][Col];
  public int player;//设置当前玩家对象
  private boolean isFirst = false;//判断是否是第一次点击的棋子,以此分开两次点击棋子的碰撞矛盾
  private int x1,y1,x2,y2;//用来保存第一次第二次选中的坐标的
  private boolean flag = true;//用来控制线程的运行
  private boolean isPlay = false;
  private Chess firstChess = null;
  private Chess secOndChess= null;//设置第一次点击的棋子和第二次选中的棋子对象

  private InetAddress myID;//自己id地址
  private InetAddress youID;//目标ID地址
  private int sendport;//发送端口
  private int receiveport = 8888;//接收端口


  public ChessPanel()//构造函数
  {
    init_map();//初始化棋盘
    //给这个面板添加鼠标监听机制
    this.addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        if(isPlay == true)//判断是否该本方下棋
        {
          SelectChess(e.getPoint());//选择要移动的棋子
          repaint();
        }
      }

      public void SelectChess(Point pos)
      {
        int x = pos.x;
        int y = pos.y;//获取此时此刻鼠标点击的位置坐标
        System.out.println("选择要移动的棋子坐标:x->"+x+" y->"+y);
        if(x > 0 && x <(Col-1)*width && y > 0 && y <(Row-1)*height)//判断鼠标是否在合理的范围,不在就直接退出
        {
          Point point = ReSetID(x,y);
          if(isFirst)//判断是否是第一次选中的棋子
          {
            x1 = point.x;
            y1 = point.y;
            //判断第一次选中的棋子是不是自己的棋子或者是不是无效棋子,不是就失败
            int id = map[x1][y1];
            if(id != -1 && chess[id].owner == player)
            {
              isFirst = false;
              firstChess = chess[id];
              System.out.println("id->"+id);
            }
            else//第一次选择的棋子无效
            {
              JOptionPane.showConfirmDialog(null, "提示", "第一次选棋无效!请重新选择!", JOptionPane.OK_OPTION);
              isFirst = true;
            }
          }
          else//第二次选中的棋子
          {
            x2 = point.x;
            y2 = point.y;
            int id = map[x2][y2];
            if(id != -1 && chess[id].owner != player)//第二次选择了敌方棋子,将敌方棋子保存起来
            {
              isFirst = true;
              secOndChess= chess[id];
              //开始判断是否可以移动棋子,如果可以就将棋子移动,并发信息给对方我们已经移动的棋子信息
              //判断是否可以移动棋子
              if(IsMoveChess(firstChess,x2,y2))//可以移动-吃棋
              {
                int idx1 = map[x1][y1];
                map[x1][y1] = -1;
                map[x2][y2] = idx1;
                chess[id] = null;
                firstChess.SetPos(x2, y2);
                repaint();
                send("move|"+String.valueOf(idx1)+"|"+String.valueOf(Row-1-x2)+"|"+String.valueOf(Col-1-y2)+"|",youID,sendport);
                if(id == 0)//吃掉了黑棋将军
                {
                  send("success|红棋赢",youID,sendport);
                  isPlay = false;
                  JOptionPane.showConfirmDialog(null, "红棋胜利", "恭喜您,您赢了!", JOptionPane.OK_OPTION);
                  return;
                }
                else if(id == 16)//吃掉了红棋大帅
                {
                  send("success|黑棋赢",youID,sendport);
                  isPlay = false;
                  JOptionPane.showConfirmDialog(null, "黑棋胜利", "恭喜您,您赢了!", JOptionPane.OK_OPTION);
                  return;
                }
                isFirst = true;
                isPlay = false;
              }
              else//表示不能吃棋,重新下棋
              {
                JOptionPane.showConfirmDialog(null, "提示", "对不起,移动棋子失败,请重新选择目标!", JOptionPane.ERROR_MESSAGE);
                isFirst = false;
              }
            }
            else if(id != -1 && chess[id].owner == player)//第二次又选择了自己的棋子,那么就将第二次选择的棋子当做第一次选择的棋子
            {
              firstChess = chess[id];
              x1 = x2;
              y1 = y2;
              isFirst = false;
            }
            else//第二次选择的棋子是空,那么就是单纯的移动棋子
            {
              secOndChess= null;
              if(IsMoveChess(firstChess,x2,y2))//可以移动-吃棋
              {
                int idx1 = map[x1][y1];
                map[x1][y1] = -1;
                map[x2][y2] = idx1;
//               chess[id] = null;
                firstChess.SetPos(x2, y2);
                send("move|"+String.valueOf(idx1)+"|"+String.valueOf(Row-1-x2)+"|"+String.valueOf(Col-1-y2)+"|",youID,sendport);
                System.out.println("第二次选中棋子为空:目标-》"+(Row-1-x2)+" "+(Col-1-y2));
                repaint();
                isFirst = true;
                isPlay = false;
              }
            }
          }
        }
      }
    });
  }

  public boolean IsMoveChess(Chess chess,int x,int y)//判断是否可以移动棋子----移动棋子的规则
  {
    if(chess.chessName.equals("将") || chess.chessName.equals("帅"))//只能走一步
    {
      int x0 = chess.point.x;
      int y0 = chess.point.y;
      if(x >= 8 && x <= 10 && y >= 4 && y <= 6)
      {
//       int x0 = chess.point.x;
//       int y0 = chess.point.y;
        if(Math.abs(x - x0) > 1 || Math.abs(y - y0) > 1)
          return false;
        else if(Math.abs(x - x0)*Math.abs(y - y0) != 0)//不能走斜线
          return false;
        else
          return true;
      }
      if(this.chess[map[x][y]].chessName.equals("将") || this.chess[map[x][y]].chessName.equals("帅") && (y0 == y))//判断两个将领之间吃棋
      {
        int min = x  x0&#63; x : x0;
        for(min = min+1; min = 8 && x <= 10 && y >= 4 && y <= 6)
      {
        int x0 = chess.point.x;
        int y0 = chess.point.y;
        if(Math.abs(x - x0) * Math.abs(y - y0) != 1)
        {
          return false;
        }
        else
          return true;
      }
      else//越界
        return false;
    }
    else if(chess.chessName.equals("象") || chess.chessName.equals("相"))//相走田字,且不能过河
    {
      if(x >= 6 && x != 11 && y >= 1 && y <= 9)
      {
        int x0 = chess.point.x;
        int y0 = chess.point.y;
        if(Math.abs(x - x0) * Math.abs(y - y0) != 4)
        {
          return false;
        }
        else if(Math.abs(x - x0) == 2 && Math.abs(y - y0) == 2)
        {
          int xm,ym;//求取中间值,防止中间有值不能走棋
          xm = x > x0&#63; x-1:x0-1;
          ym = y > y0&#63; y-1:y0-1;
          if(map[xm][ym] != -1)//表示中间有棋
            return false;
          return true;
        }
        else//防止1*4 == 4的情况出现
          return false;
      }
      else
        return false;
    }
    else if(chess.chessName.equals("马"))//马走日,防止蹩脚的情况出现
    {
      if(x >= 1 && x <=10 && y >= 1 && y <= 9)
      {
        int x0 = chess.point.x;
        int y0 = chess.point.y;
        if(Math.abs(x - x0) * Math.abs(y - y0) == 2)//判断是否走日
        {
          //判断是否蹩脚
          if(Math.abs(y - y0) == 2)
          {
            if(map[x0][y+1] != -1 && y  x0)//下边
            {
              return false;
            }
            return true;
          }    
        }
        else
          return false;
      }
      else
        return false;
    }
    else if(chess.chessName.equals("车"))//车走直线
    {
      if(x >= 1 && x <=10 && y >= 1 && y <= 9)
      {
        int x0 = chess.point.x;
        int y0 = chess.point.y;
        if(x == x0)//水平移动
        {
          int i = y  y0 &#63; y : y0;
          for(i = i+1; i  x0 &#63; x : x0;
          for(i = i+1; i = 1 && x <=10 && y >= 1 && y <= 9)
      {
        int x0 = chess.point.x;
        int y0 = chess.point.y;
        int countx = 0;
        int county = 0;
        if(x == x0)//水平移动
        {
          int i = y  y0 &#63; y : y0;
          for(i = i+1; i  x0 &#63; x : x0;
          for(i = i+1; i = 1 && y >= 1 && y <= 9)
      {
        int x0 = chess.point.x;
        int y0 = chess.point.y;
        if(x == x0 && Math.abs(y-y0) == 1)//横向只走一步,判断是否在河的这边还是那边
        {
          //如果是河的这边就不能走横向
          if(x == 6)
            return false;
          else
            return true;
        }
        if(y == y0 && x - x0 == -1)//纵向只走一步,且必须向前走
        {
          return true;
        }
        return false;
      }
      else
        return false;
    }
    return false;
  }

  public Point ReSetID(int x, int y)//重置id,将id转化成可辨识的坐标信息
  {
    int posx = (y+height/2)/height;
    int posy = (x+width/2)/width;
    return new Point(posx,posy);
  }

  public void init_map()//初始化棋盘
  {
    for(int i = 0; i "+indx);
          int posx = Integer.parseInt(s[2]);
          System.out.println("posx->"+posx);
          int posy = Integer.parseInt(s[3]);
          System.out.println("posy->"+posy);
          int x = chess[indx].point.x;
          int y = chess[indx].point.y;
          map[x][y] = -1;
          chess[indx].point.x = posx;
          chess[indx].point.y = posy;
          if(map[posx][posy] != -1)
          {
            chess[map[posx][posy]] = null;
          }
          map[posx][posy] = indx;
          repaint();
          isPlay = true;
        }
        else if(s[0].equals("quit"))//对方退出
        {
          JOptionPane.showConfirmDialog(null, "提示", "对方离开,游戏结束!", JOptionPane.OK_OPTION);
          isPlay = false;
          flag = false;//退出线程
        }

      }

    } catch (SocketException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally
    {
      if(sock != null)
      {
        sock.close();
      }
    }

  }
}

3.ChessFrame类:

package internet_chess;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class ChessFrame extends JFrame{
  private JButton start = new JButton("开始");
  private JButton end = new JButton("结束");
  private JButton lose = new JButton("认输");
  private JPanel paneUp = new JPanel();
  private ChessPanel chesspanel = new ChessPanel();
  private JPanel paneDown = new JPanel();
  private JLabel IPlabel = new JLabel("IP:");
  private JLabel otherPortlabel = new JLabel("目标端口");
  private JLabel imageicon = new JLabel();
  private JTextField ip_address = new JTextField("127.0.0.1");
  private JTextField otherPort = new JTextField("9999");

  private InetAddress myID;//自己id地址
  private InetAddress youID;//目标ID地址
  private int sendport;//发送端口
  private int receiveport = 8888;//接收端口


  public ChessFrame()//构造函数
  {
    paneDown.setLayout(new FlowLayout());
    IPlabel.setBounds(10, 10, 40, 20);
    ip_address.setBounds(new Rectangle(60,10,50,20));
    paneDown.add(IPlabel);
    paneDown.add(ip_address);
    paneDown.add(otherPortlabel);
    paneDown.add(otherPort);
    paneDown.add(start);
    paneDown.add(lose);
    paneDown.add(end);
    lose.setEnabled(false);

    imageicon.setBounds(new Rectangle(300,0,100,100));
    imageicon.setIcon(new ImageIcon("F:/Image/chess/0.png"));//标签加载图片
    paneUp.add(imageicon,BorderLayout.CENTER);

    Container con = this.getContentPane();
    con.add(paneUp,BorderLayout.NORTH);
    con.add(chesspanel,BorderLayout.CENTER);
    con.add(paneDown,BorderLayout.SOUTH);

    this.setTitle("8888网络象棋");
    this.setSize(new Dimension(600,700));
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    start.addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        try {
          String ip = ip_address.getText();//获取当前目标ip地址
          sendport = Integer.parseInt(otherPort.getText());//获取目标连接端口
          myID = InetAddress.getLocalHost();//获取本地ip地址
          youID = InetAddress.getByName(ip);//获取目标ip地址
        } catch (UnknownHostException e1) {
          e1.printStackTrace();
        }
        chesspanel.startgame(youID,sendport,receiveport);
        lose.setEnabled(true);
      }
    });

    end.addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        try{
          chesspanel.send("quit|",youID,sendport);//向对方发送离开信息,同时断开连接
          System.exit(0);
        }catch(Exception ex)
        {
          ex.printStackTrace();
        }
      }
    });

    lose.addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        try{
          chesspanel.send("lose|",youID,sendport);//向对方发送认输信息
        }catch(Exception ex)
        {
          ex.printStackTrace();
        }
      }
    });


    //加一个对方求和的按钮
  }

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    new ChessFrame();
  }

}

代码结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文介绍了在CentOS 7.x上进行端口映射配置的方法,通过修改内核和配置防火墙实现端口映射。作者分享了自己使用华为服务器进行端口映射的经验,发现网速比直连还快且稳定。详细的配置过程包括开启系统路由模式功能、设置IP地址伪装、设置端口映射等。同时,还介绍了如何监听本地端口的tcp请求,以及删除规则和开放的端口的方法。 ... [详细]
  • 缤果串口网络蓝牙调试助手的特点和下载链接
    本文介绍了缤果串口网络蓝牙调试助手的主要特点,包括支持常用的波特率、校验、数据位和停止位设置,以及以ASCII码或十六进制接收或发送数据或字符的功能。该助手还能任意设定自动发送周期,并能将接收数据保存成文本文件。同时,该软件支持网络UDP/TCP和蓝牙功能。最后,提供了腾讯微云和百度网盘的下载链接。 ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • Linux防火墙配置—允许转发
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 计算机网络计算机网络分层结构
    为了解决计算机网络复杂的问题,提出了计算机网络分层结构。计算机网络分层结构主要有OSI7层参考模型,TCPIP4层参考模型两种。为什么要分层不同产商 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
  • slmp协议和mc协议区别_TCP协议与UDP协议的区别
    TCP协议和UDP协议TCPIP协议是一个协议簇。里面包括很多协议的,UDP只是其中的一个,之所以命名为TCPIP协议,因 ... [详细]
  • UDP千兆以太网FPGA_verilog实现(四、代码前期准备UDP和IP协议构建)
    UDP:userDatagramprotocol用户数据报协议无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETFRFC76 ... [详细]
  • SQL Server 2008 到底需要使用哪些端口?
    SQLServer2008到底需要使用哪些端口?-下面就来介绍下SQLServer2008中使用的端口有哪些:  首先,最常用最常见的就是1433端口。这个是数据库引擎的端口,如果 ... [详细]
  • 三、寻找恶意IP并用iptables禁止掉找出恶意连接你的服务器80端口的IP,直接用iptables来drop掉它;这里建议写脚本来运行, ... [详细]
  • Ansem 最新雄文:软着陆后,加密市场下阶段趋势与核心叙事
    市场最糟糕的时候已经过去,以太坊合并前不太会看到新的低点;但仍需来自关注宏观市场的不确定风险。撰文:Ansem ... [详细]
  • IP、ARP、TCP、UDP、ICMP、DNS、路由协议、DHCP协议的缺陷,容易受到的攻击,以及防御措施1、IP协议1.1、介绍: ... [详细]
  • 1、概述首先和大家一起回顾一下Java消息服务,在我之前的博客《Java消息队列-JMS概述》中,我为大家分析了:然后在另一篇博客《Java消息队列-ActiveMq实战》中 ... [详细]
  • 域名解析系统DNS
    文章目录前言一、域名系统概述二、因特网的域名结构三、域名服务器1.根域名服务器2.顶级域名服务器(TLD,top-leveldomain)3.权威(Authoritative)域名 ... [详细]
  • NFS文件共享系统
    1、概述:NFS(NetworkFileSystem)意为网络文件系统,它最大的功能就是可以通过网络,让不同的机器不同的操作系统可以共享 ... [详细]
author-avatar
beat_小然
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有