当前位置: 首页 > 编程日记 > 正文

Linux X Window System运行原理和启动过程

本文主要说明X Window System的基本运行原理,其启动过程,及常见的跨网络运行X Window System。 一) 基本运行原理 X Window System采用C/S结构,但和我们常见的C/S不同。常见的C/S结构中,称提供服务的一方为server,即服务器端(如HTTP服务,FTP服务等),使用服务的称

本文主要说明X Window System的基本运行原理,其启动过程,及常见的跨网络运行X Window System。

一) 基本运行原理 
X Window System采用C/S结构,但和我们常见的C/S不同。常见的C/S结构中,称提供服务的一方为server,即服务器端(如HTTP服务,FTP服务等),使用服务的称为client,即客户端。但在X Window System中,client是执行程式的一方,在上面执行各种X程式,而server则是负责显示client运行程式的窗口的一方。

X Window System的组成能够分为X server,X client,X protocol三部分。X server主要控制输入输出,维护字体,颜色等相关资源。他接受输入设备的输入信息并传递给X client,X client将这些信息处理后所返回的信息,也由X server负责输出到输出设备(即我们所见的显示器)上。X server传递给X client的信息称为Event,主要是键盘鼠标输入和窗口状态的信息。X client传递给X server的信息则称为Request,主要是需要X server建立窗口,更改窗口大小位置或在窗口上绘图输出文字等。X client主要是完成应用程式计算处理的部分,并不接受用户的输入信息,输入信息都是输入给X server,然后由X server以Event的形式传递给X client(这里感觉类似Windows的消息机制,系统接收到用户的输入信息,然后以消息的形式传递给窗口,再由窗口的消息处理过程处理)。X client对收到的Event进行相应的处理后,假如需要输出到屏幕上或更改画面的外观等,则发出Request给X server,由X server负责显示。

常见的情况是X server和X client都在同一台电脑上运行,但他们也可分别位于网络上不同的电脑上。在X Window System中,X client是和硬件无关的,他并不关心您使用的是什么显卡什么显示器什么键盘鼠标,这些只和X server相关。我们平常安装完XFree86后运行xf86config或xf86cfg进行的配置实际上只是和X server有关,能够说就是配置X server吧,不配置照样能够运行X client程式(如:xeyes -display xserver:0就能够在xserver这台机器上的0号屏幕(屏幕编号displaynumber为0)上显示那对大眼睛了)。

X protocol就是X server于X client之间通信的协议了。X protocol支持现在常用的网络通信协议。我只能测试TCP/IP,能够看到X server侦听在tcp 6000端口上。那X protocol就是位于运输层以上了,应该属于应用层吧?。
总结下运行过程吧: 
(1) 用户通过鼠标键盘对X server下达操作命令 
(2) X server利用Event传递用户操作信息给X client 
(3) X client进行程式运算 
(4) X client利用Request传回所要显示的结果 
(5) X server将结果显示在屏幕上

二) 启动过程 
我们从控制台进入X一般是用startx命令。下面就从startx分析起。首先man startx和man xinit能够看到staratx和xinit的使用方法:
startx [[client] options .....] [-- [server] options ....] 
xinit [[client] options ] [-- [server] [display] options] 
把上面[client]和[server]分别称为client程式和server程式。man手册里写明其必须以/或./开头。 
下面看看startx这个脚本,中文为我加的注释,这个脚本是安装x-window-system-core后得到的,都是XFree86,不同发行版的linux里该脚本应该大同小异:
#!/bin/sh 
userclientrc=$HOME/.xinitrc #用户的client定义文档 
userserverrc=$HOME/.xserverrc #用户的server定义文档 
sysclientrc=/usr/X11R6/lib/X11/xinit/xinitrc #系统的client 
sysserverrc=/usr/X11R6/lib/X11/xinit/xserverrc #系统的server 
defaultclient=/usr/X11R6/bin/xterm #默认的client程式 
defaultserver=/usr/X11R6/bin/X #默认的server程式 
defaultclientargs="" #下面定义了client和server的参数变量 
defaultserverargs="" 
clientargs="" 
serverargs=""

#假如用户client文档存在则使用用户文档里定义的client,否则使用系统定义的client 
if [ -f $userclientrc ]; then 
defaultclientargs=$userclientrc 
elif [ -f $sysclientrc ]; then 
defaultclientargs=$sysclientrc 
fi

#假如用户server文档存在则使用用户文档里定义的server,否则使用系统定义的server 
if [ -f $userserverrc ]; then 
defaultserverargs=$userserverrc 
elif [ -f $sysserverrc ]; then 
defaultserverargs=$sysserverrc 
fi

#下面循环处理client和server的参数 
whoseargs="client" 
while [ x"" != x ]; do #若第一个参数为空,退出循环 
case "" in 
# '' required to prevent cpp from treating "/*" as a C comment. 
/''*|./''*) #假如是/*或./*形式(xinit程式需要其参数里的client程式和server程式必须以/或./开头,否则会被视为client程式和server程式的参数,见man xinit)
if [ "$whoseargs" = "client" ]; then #假如当前是在处理client的参数 
if [ x"$clientargs" = x ]; then #假如clientargs为空,则赋值给client变量,也即上面#startx使用方法里的[client]参数
client="" 
else 
clientargs="$clientargs " #否则clientargs赋值为$clientargs ,即上面#startx使用#方法里的options参数
fi 
else #当前在处理server的参数,代码的含义同上 
if [ x"$serverargs" = x ]; then 
server=""

else 
serverargs="$serverargs " 
fi 
fi 
;; 
--)#假如为--,则表示开始处理server的参数,--为client和server参数的分界 
whoseargs="server" 
;; 
*) 
if [ "$whoseargs" = "client" ]; then #处理给client程式的参数 
clientargs="$clientargs " 
else #处理给server程式的参数 
# display must be the FIRST server argument
#屏幕编号必须为第一个给server程式的参数,以的形式(x为数字),这可从上面startx和xinit 的使用
#方法的区别看出,xinit多了个[display],这里即过滤出这个[display]。试试看这两个命令: 
#xinit /usr/bin/X11/xeyes -display localhost:1 -- /usr/bin/X11/X :1 -dpi 70& 
#xinit /usr/bin/X11/xeyes -display localhost:1 -- /usr/bin/X11/X -dpi 70 :1& 
#即可看出不把屏幕编号作为第一个server参数的后果 
if [ x"$serverargs" = x ] && expr "" : ':[0-9][0-9]*$' > /dev/null 2>&1; then 
display="" 
else #处理屏幕编号以外的参数 
serverargs="$serverargs " 
fi 
fi 
;; 
esac 
shift #任何参数左移一次 
done

# process client arguments 
if [ x"$client" = x ]; then #假如client程式为空 
# if no client arguments either, use rc file instead 
if [ x"$clientargs" = x ]; then #且clientargs为空,赋值$defaultclientargs给client程式 
client="$defaultclientargs" 
else 
client=$defaultclient #使用默认的client程式 
fi 
fi 

# process server arguments处理server参数,同上 
if [ x"$server" = x ]; then 
# if no server arguments or display either, use rc file instead 
if [ x"$serverargs" = x -a x"$display" = x ]; then 
server="$defaultserverargs" 
else 
server=$defaultserver 
fi 
fi 
#…………省略授权代码若干

xinit $client $clientargs -- $server $display $serverargs #把处理过的参数交由xinit程式处理 
#………… 
由上面代码能够得出startx主要是置X client和X server所在的位置,并处理相关参数,最后交给xinit处理。能够看出startx 配置X client的位置是先搜寻$HOME/.xinitrc,然后是/etc/X11/xinit/xinitrc;配置X server的位置是先搜寻$HOME/.xserverrc,然后是/etc/X11/xinit/xserverrc。这就解释了我们平常为什么说启动X Window时用户目录下的.xinitrc和.xserverrc文档优先级要高。所以我们用startx命令启动X时,假如用户目录存在.xinitrc和.xserverrc文档,则实际上等价于命令xinit $HOME/.xinitrc -- $HOME/.xserverrc 。假如用户目录不存在那两个文档,则等价于xinit /usr/X11R6/lib/X11/xinit/xinitrc -- /usr/X11R6/lib/X11/xinit/xserver。别的情况类推。

至于xinit,则根据startx传过来的参数启动X server,成功后根据xinitrc启动X client。 
以上即为X Window System的启动过程,startx只是负责一些参数传递,真正的X启动由xinit实现。实际上能够分为启动X server和启动X client两部分。下面在用户目录下构造.xinitrc(即X client)和.xserverrc(即X server)文档。在.xserverrc里写入/usr/bin/X11/X :1。.xinitrc里写入/usr/bin/X11/xeyes -display localhost:1。这就是最简单的X server X client了,只但是把屏幕编号从默认的0改为了1,这里X server即是/usr/bin/X11/X 程式,X client即是/usr/bin/X11/xeyes 程式。 
总结下单机用startx启动过程吧: 
(1) startx置X client和X server的位置,处理参数并调用xinit 
(2) xinit根据传过来的参数启动X server,成功后呼叫X client 
(3) 根据xinitrc配置相关资源,启动窗口管理器,输入法和其他应用程式等X client程式。

但还未搞清楚gnome是怎么起来的!gnome当然属于X client了,看上面启动过程第(3)步。 
这里分两种情况看吧,第一种是用系统的xinitrc文档。看/etc/X11/xinit/xinitrc文档(我的sarge装x-window-system-core和gnome-core),里面只包含了. /etc/X11/Xsession一句话。接着看/etc/X11/Xsession这个脚本,只看关键部分吧。最后面有:

SESSIONFILES=$(run_parts $SYSSESSIONDIR) 
if [ -n "$SESSIONFILES" ]; then 
for SESSIONFILE in $SESSIONFILES; do 
. $SESSIONFILE 
done 
fi 
exit 0 

接着看run_parts(),位于本文档中间: 
run_parts () { 
# until run-parts --noexec is implemented 
if [ -z "" ]; then 
internal_errormsg "run_parts() called without an argument." 
fi 

if [ ! -d "" ]; then 
internal_errormsg "run_parts() called, but "" does not exist or is" 
"not a directory." 
fi

for F in $(ls ); do 
if expr "$F" : '[[:alnum:]_-] $' > /dev/null 2>&1; then

if [ -f "/$F" ]; then 
echo "/$F" 
fi 
fi 
done 
}

大概意思就是run_parts () 把$SYSSESSIONDIR目录下的文档名取出来赋值给$SESSIONFILES,然后循环运行该目录下的文档。看看该目录,即/etc/X11/Xsession.d目录,能够看到几个以数字开头的文档,实际上这些数值就表示了这几个文档被运行的优先级,数字小的优先级高,因为在上面的run_parts () 里是用ls命令显示该目录下的文档,所以前面数字小的被ls时显示在前面,所以被
for SESSIONFILE in $SESSIONFILES; do 
. $SESSIONFILE 
done

这个for循环执行时也先被执行。看到/etc/X11/Xsession.d目录下有个55gnome-session_gnomerc文档,里面提到了STARTUP变量。然后运行:
xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP *
看到50xfree86-common_determine-startup文档。里面有 
if [ -z "$STARTUP" ]; then 
if [ -x /usr/bin/x-session-manager ]; then 
STARTUP=x-session-manager 
elif [ -x /usr/bin/x-window-manager ]; then 
STARTUP=x-window-manager 
elif [ -x /usr/bin/x-terminal-emulator ]; then 
STARTUP=x-terminal-emulator 
fi 
fi

即配置启动程式,实际上配置STARTUP变量,假如以上程式都没有找到,则会报错退出,即X环境没有被启动。再运行 
xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP *
看到优先级最低也即最后被运行的99xfree86-common_start文档,里面只有一句话: 
exec $STARTUP 
好了,到这里就启动我们的X client了,终于完了^_^。总结下这第一种方式的启动过程,简单的说就是依次顺序查找/usr/bin/x-session-manager ,x-window-manager,/usr/bin/x-terminal-emulator 这三个文档。假如存在则启动之,也即X client。假如三个都不存在则报错退出了。看/usr/bin/x-session-manager文档能够看到是个符号连接,最终连接到/usr/bin/gnome-session,也就是gnome 了。至于我们在gnome 启动时可能会配置启动输入法等程式,那就归gnome-session管了,也就不再分析了。能够试着把/usr/bin/x-session-manager 改为指向xfce4-session(假如安装了的话) ,再startx就会启动xfce4环境了。大概RedHat的switchdesk工具就是改这个连接实现的吧?。或删掉/usr/bin/x-session-manager ,再startx,只启动了/usr/bin/x-window-manager 所指向的window manager了吧,我这里是blackbox。

下面看第二种情况,即用户目录的xinitrc文档$HOME/.xinitrc。对比hiweed-debian-desktop_0.55_i386,存在$HOME/.xinitrc文档,在里面有exec xfce4-session。故其X client能够说最主要的x-session-manger是从$HOME/.xinitrc启动的。也就不会经过上面第一种情况的执行过程了。

终于把gnome(或说x-session-manger)的启动过程弄明白了,下面说点别的吧。xinit程式同时启动X server和X client,这在单机上还可。要是位于网络上的两台电脑分别是client和server,则xinit就无能为力了。这时就得靠纯“手工”来启动X了。下面简单的“手工”启动X server和X client:在CUI模式下运行命令:
xdkui@Debian:~$X :1&

看到了一个灰色的全屏幕和一个鼠标指针,这就是X server了,其屏幕编号为1。下面构造X client,按Ctrl Alt F1回到刚才的CUI(Ctrl Alt F7对应本机的第一个启动的X server,Ctrl Alt F8对应第二个,有人说F7对应屏幕编号为0的X server实际上是不对的,假如第一个启动的屏幕编号为1,第二个启动的编号为0,则F7对应1屏幕,F8对应0屏幕),运行命令:xdkui@Debian:~$xeyes -display localhost:1&

然后按Ctrl Alt F7,看到我们的X client也就是xeyes了吧。再回到CUI,运行 
xdkui@Debian:~$X& 
开启一个屏幕编号0的X server,CUI下再运行 
xdkui@Debian:~$xterm&

这时Ctrl Alt F7对应屏幕编号1;而F8对应屏幕编号0,且其X client为xterm。先退出上面的两个X server,下面复杂点手动启动我们的gnome吧,首先
xdkui@Debian:~$X& 
然后 
xdkui@Debian:~$gnome-session

看到的就和用startx 启动的X相同了,这时X server是X这个程式,X client是gnome-session及其启动的窗口管理器等程式。看到这里感觉xinit用处并不大(??不知是否正确),简单的脚本就能够实现。本来想把xinit反汇编了分析下,可懒得搞了^_^这是位于本机的情况,对于X server和X client位于不同主机的情况见下面本文第三部分。

个人感觉对于X Window System,搞清楚X server和X client关系很重要。一般X server很简单,就是/usr/bin/X11/X程式;X client则花样繁多,从高级的CDE,GNOME,KDE,到低级一点的只有twm,Window Maker,blackbox等窗口管理器,再到最简陋的只有xterm,rxvt,xeyes等单个x程式。正是由于X client的各种搭配,使得我们的X Window System看起来多样化。这可能也是X Window System最大的卖点之一吧 ^_^

三) 跨网络运行X Window System 
一般用来做服务器的系统(Linux,FreeBSD,Solaris等等)都不会装X server,甚至很多都没有显示器。这样能够在这些系统里安装简单的X client,以GUI的方式远程显示在管理员们所坐的X server里。我们实验室用FreeBSD做网关,提供WWW,FTP服务,一般在管理员的本地机器起个X server,然后ssh或telnet上网关运行X client程式显示在本地显示器上,当然,也可用XDMCP(X Display Manager Control Protocol),man xsession里提到/etc/X11/Xsession一般被startx(我的/etc/X11/xinit/xinitrc里调用Xsession脚本)或display manager调用,但有的display manager只调用Xsession而不是xinitrc,故为了startx和display manager两种方式下都可正常启动GUI,最好把X client启动的程式放在Xsession文档里。远程运行X client程式需要配置DISPLAY环境变量,配置为 主机名称:屏幕编号(如192.168.1.2:0,则表示X server是192.168.1.2这台机器上的0号屏幕);或是给X client程式加个—display参数。由于条件限制,只测试了位于TCP/IP网络环境,X server为192.168.1.2,X client为192.168.1.1。

1) Windows系统做X server 
a) 用ssh或telnet方式 
Windows下面的X server软件有很多种,我这里使用X-win32。在Windows里运行X-win32程式,则相当于本地机器是个X server。远程登录上Debian(我这里是用VMware仿真网络环境,直接进虚拟机即可^_^),运行:
xdkui@xclient:~$export DISPLAY=192.168.1.2:0 
xdkui@xclient:~$xterm& 
这时即在Windows里的X server里看到了xterm了,至于X client还运行什么程式就看您的需要了,文档管理器阿,资源查看器等。当然,这里X-win32要配置好授权,似乎默认是禁止接入控制,即任何X client都可使用这个X server。

b) XDMCP方式 
常见的Display Manager有xdm,gdm,kdm等。我这里使用的是gdm。需要修改gdm的配置文档/etc/X11/gdm/gdm.conf,修改[xdmcp]段的Enable=true,使得能够远程登录,在X client运行gdm。
在X-win32里建一个XDMCP的session,查询方式,填入IP为运行gdm的机器地址。连接,即可看到登录界面,下面的就不用说了,享受吧

2) Linux和Linux互联 
a) ssh或telnet方式 
在linux本地起个X server,需要注意授权问题,建立文档/etc/X0.hosts,填入X client的IP192.168.1.1,其中X0.hosts表示本地第0个屏幕允许连接的X client地址,建立X1.hosts文档则是本地第1个屏幕允许连接的X client地址,以此类推,man xserver里有。运行
xdkui@xserver:~$X& 
运行该程式时别加-nolisten参数,否则不会在网络上侦听。 
这个时候Ctrl Alt F7是X server,返回Ctrl Alt F1还能够ssh上X client机器上。 
然后登录上X client,运行 
xdkui@xclient:~$xterm –display 192.168.1.2:0 
即可在本地的X server里看到xterm了,假如有的话,还可把gnome-session也显示在本地来。同样能够在linux里的VMware里做这个测试,需要用点手腕了^_^见下

b) XDMCP方式 
在我们的X client里运行gdm(别忘了修改gdm.conf),然后在本地X server的CUI下面运行X -query 192.168.1.1(X client开gdm机器的地址)。能够看到登录界面了吧。
我是在linux里的VMware里做的测试,说说所用的手腕吧。在Ctrl Alt F1的CUI下正常运行startx&启动GUI,这时Ctrl Alt F7即为我的X server,X client启动的gnome,然后在这里运行VMware打开Debian虚拟机,并运行gdm。然后回到Ctrl Alt F1,运行X :1 -query 192.168.1.1。看到登录界面了吧。这时Ctrl Alt F7为我的0号屏幕,里面运行了虚拟机。Ctrl Alt F8为1号屏幕,在远程GUI登录X client。相当于我在本地起了两个X server。 

X Window System设计的真是相当神奇,使用方法更是眼花缭乱。

总结:

X Window System的组成能够分为X server,X client,X protocol三部分。X server主要控制输入输出,维护字体,颜色等相关资源。他接受输入设备的输入信息并传递给X client,X client将这些信息处理后所返回的信息,也由X server负责输出到输出设备(即我们所见的显示器)上。X server传递给X client的信息称为Event,主要是键盘鼠标输入和窗口状态的信息。X client传递给X server的信息则称为Request,主要是需要X server建立窗口,更改窗口大小位置或在窗口上绘图输出文字等。X client主要是完成应用程式计算处理的部分,并不接受用户的输入信息,输入信息都是输入给X server,然后由X server以Event的形式传递给X client(这里感觉类似Windows的消息机制,系统接收到用户的输入信息,然后以消息的形式传递给窗口,再由窗口的消息处理过程处理)。X client对收到的Event进行相应的处理后,假如需要输出到屏幕上或更改画面的外观等,则发出Request给X server,由X server负责显示。

startx主要是置X client和X server所在的位置,并处理相关参数,最后交给xinit处理。能够看出startx 配置X client的位置是先搜寻$HOME/.xinitrc,然后是/etc/X11/xinit/xinitrc;配置X server的位置是先搜寻$HOME/.xserverrc,然后是/etc/X11/xinit/xserverrc。这就解释了我们平常为什么说启动X Window时用户目录下的.xinitrc和.xserverrc文档优先级要高。所以我们用startx命令启动X时,假如用户目录存在.xinitrc和.xserverrc文档,则实际上等价于命令xinit $HOME/.xinitrc -- $HOME/.xserverrc 。假如用户目录不存在那两个文档,则等价于xinit /usr/X11R6/lib/X11/xinit/xinitrc -- /usr/X11R6/lib/X11/xinit/xserver。别的情况类推。

至于xinit,则根据startx传过来的参数启动X server,成功后根据xinitrc启动X client。 
以上即为X Window System的启动过程,startx只是负责一些参数传递,真正的X启动由xinit实现。实际上能够分为启动X server和启动X client两部分。下面在用户目录下构造.xinitrc(即X client)和.xserverrc(即X server)文档。在.xserverrc里写入/usr/bin/X11/X :1。.xinitrc里写入/usr/bin/X11/xeyes -display localhost:1。这就是最简单的X server X client了,只但是把屏幕编号从默认的0改为了1,这里X server即是/usr/bin/X11/X 程式,X client即是/usr/bin/X11/xeyes 程式。 
总结下单机用startx启动过程吧: 
(1) startx置X client和X server的位置,处理参数并调用xinit 
(2) xinit根据传过来的参数启动X server,成功后呼叫X client 
(3) 根据xinitrc配置相关资源,启动窗口管理器,输入法和其他应用程式等X client程式。

启动X窗口的分步骤方法:

(1) xinit 
(2) gnome-session

尚存问题:

Gnome 和Gnome2 在配置文档和启动过程有何不同

在Fedora Gnome2中 假如是root用户 /root/.gnome2/ 中是否需要session目录 有何作用

转载于:https://www.cnblogs.com/bigben0123/p/3173575.html

相关文章:

悬浮球 / 悬浮按钮 / 辅助按钮

原文链接:https://github.com/jinht/FloatingBall类似于 iOS 系统自带的 AssistiveTouch / 京东 / 聚划算 / 建行等的辅助按钮 —— 由anticipate_91分享FloatingBall Function Description 这是一个类似于iOS系统自带的AssistiveTouch/京东《我的》部分的悬浮按钮等…

手动部署OpenStack环境(四:安装控制器必备软件)

任务四、安装控制器必备组件 4.1、安装MySQL服务(controller0) 4.2、安装Rabbitmq消息队列(controller0) 4.3、Keystone认证(controller0) 4.4、glance的安装与配置(controller0) 4.…

cocoaPods安装、更新第三方库

pod install 换成 pod install --verbose --no-repo-update pod update 换成 pod update --verbose --no-repo-update这是因为:目前,cocoaPods正在被墙中......转载于:https://www.cnblogs.com/hello-Huashan/p/5542456.html

iOS 性能优化总结

原文链接:https://github.com/skyming/iOS-Performance-Optimization关于 iOS 性能优化梳理: 基本工具、业务优化、内存优化、卡顿优化、布局优化、电量优化、 安装包瘦身、启动优化、网络优化等 —— 由_skyming_分享关于iOS 性能优化梳理: …

TCP/IP协议分析

一;前言 学习过TCP/IP协议的人多有一种感觉,这东西太抽象了,没有什么数据实例,看完不久就忘了。本文将介绍一种直观的学习方法,利用协议分析工具学习TCP/IP,在学习的过程中能直观的看到数据的具体传输过程。 为了初学者…

手动部署OpenStack环境(五:新建网络及部署虚拟机)

任务五、新建网络及部署虚拟机 5.1、配置安全组规则 5.2、新建网络 5.3、创建云主机 任务五、新建网络及部署虚拟机 5.1、配置安全组规则 5.1.1、配置安全组; 5.2、新建网络。 5.2.1、创建外部网络; 5.2.2、网络地址为外部网络连接的子网地址&#xff1b…

C++基础day01 程序设计方法的发展历程

类把属性和方法作了封装! 总结: 面向过程程序设计:数据结构 算法 主要解决科学计算问题,用户需求简单而固定 特点: 分析解决问题所需要的步骤 利用函数实现各个步骤 依次调用函数解决问题 问题: 软件可重用…

【android】android中activity的生命周期

activity生命周期: 实例代码: 1 public class DemoActivity extends Activity {2 3 //1、activity第一次被创建的时候,执行4 Override5 public void onCreate(Bundle savedInstanceState) {6 super.onCreate(savedIn…

Xcode消除编译器警告

Whenever,Xcode警告对于我们来说都相当重要,提醒我们可能存在的错误。但是有时候,我们知道一切都好,everything is in the palm of my hand,我们想要消除那些警告。自己项目的警告 比如我们定义一个designated initial…

手动部署OpenStack环境(六:出现的问题与解决方案总结)

排错一:keystone服务安装中demo用户表单没信息。 排错思路: 组件安装是否有问题;用户创建畲缶有问题;用户认证信息是否合适;原因:用户的认证信息配置错误。 解决方案: a)删除有关demo用户的所有…

一劳永逸,iOS 自定义 ActionSheet 封装流程

原文链接:http://www.jianshu.com/p/cfb87a7db7b1本文为 iOS 自定义视图封装《一劳永逸》系列的第四期,旨在提供封装思路,结果固然重要,但理解过程才最好。授人以鱼不如授人以渔。 —— 由卖报的小画家Sure分享前言 本文为iOS自定…

cocoapods更新

使用sudo gem install cocoapods更新提示: ERROR: While executing gem ... (Errno::EPERM) Operation not permitted 改为:sudo gem install -n /usr/local/bin cocoapods --pre刷刷刷完成更新。但是马上发下更新后使用pod install又发现一个问题 The …

创建对象_工厂方法(Factory Method)模式 与 静态工厂方法

工厂方法模式: 定义:为创建对象定义一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟至子类。应用场景:客户类不关心使用哪个具体类,只关心该接口所提供的功能;创建过程比较复杂&#xff0c…

数据通信技术(一:IP划分)

一、某公司生产部有50人,销售部有100人,财务部有25人,客服部有12人,没个员工配置一台主机,该公司有192.168.100.1/24的网段可用,应该如何划分子网。 销售部(100)台:/25 …

团队作业—第二阶段06

站立会议: 继续数据库的连接编程。 任务进度: 实现数据的输出。 站立会议照片: 任务看板: 燃尽图: 转载于:https://www.cnblogs.com/cpljlgs/p/5546157.html

Fade 数字切换动效

原文链接:http://www.jianshu.com/p/983674e6f4ef根据原型高度还原的一个动效作品。希望可以通过审核。谢谢。 —— 由Bear1494735376123分享欢迎同样喜爱动效的你加入 iOS动效特攻队–>QQ群:547897182 iOS动效特攻队–>熊熊:64807025…

fieldset 使用小案例

有初学者问到如何做出如下页面: 对应的代码如下: <fieldset><legend>★审核状态</legend><input name"state" type"radio" class"input1" value"1" />已审核<input name"state" type"radio…

数据通信技术(二:交换机配置管理)

交换机配置与管理&#xff08;思科模拟器&#xff09; 1.从用户模式进入特权模式,并进入配置模式设置进入特权模式的密码; 2.进入交换机的端口模式并进行端口状态的设置; 用新密码登录并查看接口状态信息,重启交换机;4.硬件和软件版本查询: 5.设备CPU的利用率: 6.检查设备的MA…

iOS之各种区别

作者 APP叫我取个帅气的昵称 关注 2017.05.15 10:47* 字数 140 阅读 1273评论 7喜欢 51写在前面&#xff1a;本文持续更新&#xff0c;也欢迎简友提供更多的关于iOS&#xff08;包括swift&#xff09;中的区别 1. _ _block和 _ _weak修饰符的区别的&#xff1a; (1). _ _block不…

lightoj 1014

lightoj 1014 Ifter Party 链接&#xff1a;http://www.lightoj.com/volume_showproblem.php?problem1014 题意&#xff1a;给你两个数 p, l&#xff0c;求 cha&#xff08;cha p-l&#xff09;的约数&#xff0c;当约数大于 l 时&#xff0c;按从小到大输出 思路&#xff1a…

poj 2681 字符串

http://poj.org/problem?id2681 给你任意长度的字符串&#xff0c;找出两串字符中不相同的字符个数&#xff08;总数&#xff09; #include<string> #include<cstring> #include<iostream> #include<cstdio> using namespace std; int main() {int n;…

数据通信技术(三:VLAN划分)

VLAN划分 1.配置环境 &#xff1a;创建4台PC机&#xff0c;并为PC机配置IP PC0&#xff1a;192.168.1.1/24 PC1&#xff1a;192.168.1.2/24 PC2&#xff1a;192.168.1.3/24 PC3&#xff1a;192.168.1.4/24 2.修改交换机名称&#xff1a; 创建VLAN1和VLAN2&#xff1a;…

CSS(2 )-- CSS样式大全

常用css样式大全Author&#xff1a;xu_shuyi201504039.CSS颜色代码大全http://www.cnblogs.com/axing/archive/2011/04/09/CSS.html1.CSS文字属性color : #999999; /*文字颜色*/font-family : 宋体,sans-serif; /*文字字体*/font-size : 9pt; /*文字大小*/font-style:itelic; /…

java io读书笔记(6) Writing Arrays of Bytes

显而易见&#xff0c;一次性写出一堆数据&#xff0c;要比一个byte一个byte的写&#xff0c;快多了&#xff0c;因此&#xff0c;outputstream&#xff0c;给出了2个增强型的write&#xff1a; public void write(byte[] data) throws IOException public void write(byte[] da…

iOS 自定义双向滑块Slider

ZPSlider 一个双向滑块的Slider 前提 这个是在一次和朋友吃饭的时候&#xff0c;我们唠嗑的时候他说的一个需求。因为系统的Slider是只有一个滑块的&#xff0c;而且没有分段滑动的效果。 这不最近都在研究这么个需求。 How to use it -(instancetype)initWithFrame:(CGRec…

数据通信技术(四:链路聚合)

1、修改交换机名称 2、配置A交换机数据 3、配置B交换机数据 4、创建VLAN 5、互拼验证 6、去掉一条链路再进行验证 数据通信技术&#xff08;一&#xff1a;IP划分&#xff09; https://blog.csdn.net/qq_37823605/article/details/90345408 数据通信技术&#xff08;二&#xf…

iOS图片,视频上传视频内容旋转

#前言 我最近在接手一个智能盒子的iOS应用&#xff0c;上面有一个功能是这样的。把你本地的照片和视频可以甩屏到你绑定的盒子上。 我的上一位前辈做的时候必须要求再同一个局域网&#xff0c;但是当我做的时候要求不同的局域网也要实现这样的一个功能&#xff0c;优化用户的使…

jackson 解析json问题

1、json串中有key为A&#xff0c;但指定转换的mybean中未定义属性A&#xff0c;会抛异常。处理&#xff1a;mapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)&#xff0c;加上这一条&#xff0c;就没问题了&#xff0c;正常转换。 2、 默认的json串&#xff0c;如…

【转】UIColor对颜色的自定义

原文网址&#xff1a;http://blog.sina.com.cn/s/blog_5f19ccb10101bhqh.html 在iOS开发中&#xff0c;我们使用UIColor来对我们的界面进行颜色设置&#xff0c;一般我们通过以下两种方法使用UIColor&#xff1a;1,label.textColor [UIColor blueColor];2,label.textColor [U…

数据通信技术(八:OSPF单区域配置实验)

OSPF单区域配置实验(Cisco) 一&#xff0e;知识准备 1.掌握了OSPF动态路由协议的定义和功能&#xff1b; 2.掌握了OSPF动态路由协议的特征和工作原理。 二&#xff0e;实验目的 掌握OSPF动态路由单区域的基本配置方法和结果验证。 掌握OSPF单区域配置的作用 三&#xff…