CentOS5.3安装Oracle11g(图文)(五)

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://fantlam.blogbus.com/logs/43415872.html

接下来这一步很重要,oracle可以检测你的环境看你满足要求了没有

大家可以看到我还有三个警告

找了一下错误地方 发现一个是swap不足 它需要1.5G 我的才1.4G 不足 怎么办?

还好有解决方案:在linux下增加临时swap空间

step 1:

  #dd if=/dev/zero of=/home/swap bs=1024 count=500000

  注释:of=/home/swap,放置swap的空间; count的大小就是增加的swap空间的大小,1024就是块大小,这里是1K,所以总共空间就是bs*count=500M

step 2:

  # mkswap /home/swap

  注释:把刚才空间格式化成swap各式

step 3:

  #swapon /home/swap

  注释:使刚才创建的swap空间

如果想关闭刚开辟的swap空间,只需命令:#swapoff

OK,问题解决

第二个问题是 少了rpm包

Oracle ODBC Drivers

If you intend to use ODBC, then you should install the most recent ODBC Driver

Manager for Linux. You can download and install the Driver Manager from the

following link:

On Linux x86

On Asianux 3, Oracle Enterprise Linux 5, and Red Hat Enterprise Linux 5:

unixODBC-2.2.11 (32 bit) or later

unixODBC-devel-2.2.11 (32 bit) or later

原来我还少了这两个包 用FileZilla传过去安装 问题解决

还有一个是

net.core.rmem_default需要的值是 4194304 而我只有262144 奇怪 文档里是这么写的

kernel.shmall = 2097152

kernel.shmmax = 2147483648

kernel.shmmni = 4096

kernel.sem = 250 32000 100 128

net.ipv4.ip_local_port_range = 1024 65000

#net.core.rmem_default = 262144

net.core.rmem_default = 4194304

net.core.rmem_max = 4194304

net.core.wmem_default = 262144

net.core.wmem_max = 262144

把它改过来 问题解决

没有警告了 检验通过 可以真正安装了!!!

下一步 暂不安装数据库先 选择仅安装软件 不然会很久 数据库待会再建

不用修改 继续下一步

OK 可以安装了

安装过程需要一些时间

提示要运行脚本

直接把两个脚本执行 按默认的走

到此为止 oracle软件就算安装完成了 接下去是创建数据库

/etc/sysctl.conf 文件里面

CentOS5.3安装Oracle11g(图文)(四)

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://fantlam.blogbus.com/logs/43414724.html

进入home目录 解压刚刚传进去的oracle 11g

[root@localhost home]# unzip linux_11gR1_database_1013.zip

[root@localhost home]# ls -l

总计 1803272

drwxr-xr-x 5 root root       4096 2008-10-07 database

-rw-r–r– 1 root root      11244 08-02 23:36 libaio-devel-0.3.106-3.2.i386.rpm

-rw-r–r– 1 root root 1844527800 08-02 23:47 linux_11gR1_database_1013.zip

-rw-r–r– 1 root root     173049 08-02 23:36 sysstat-7.0.2-3.el5.i386.rpm

[root@localhost home]# mv database/ /fantlam (移动到fantlam目录)

[root@localhost home]# cd /fantlam

[root@localhost fantlam]# chown -R oracle:oinstall database/ R表示递归

现在已经可以安装了,由于安装需要借助图形界面,所以我们进入centos里面操作

[root@localhost ~]# su – oracle
[oracle@localhost ~]$ ls
[oracle@localhost ~]$ cd /fantlam
[oracle@localhost fantlam]$ ls
database oracle
[oracle@localhost fantlam]$ cd database
[oracle@localhost database]$ ls
doc install README runInstaller stage welcome.html
[oracle@localhost database]$ ./runInstaller
正在启动 Oracle Universal Installer…

检查临时空间: 必须大于 80 MB。   实际为 7283 MB    通过
检查交换空间: 必须大于 150 MB。   实际为 1498 MB    通过
检查监视器: 监视器配置至少必须显示 256 种颜色
    >>> 无法使用命令 /usr/bin/xdpyinfo 自动检查显示器颜色。请检查是否设置了 DISPLAY 变量。    未通过 <<<<

未通过某些要求检查。必须先满足这些要求,

然后才能继续安装,那时将重新检查这些要求。

是否继续? (y/n) [n] y

[oracle@localhost database]$ xhost local:oracle
Xlib: connection to ":0.0" refused by server
Xlib: No protocol specified

xhost: unable to open display ":0.0"

由于不是root所以报错
[oracle@localhost database]$ su – root
口令:
[root@localhost ~]# xhost local:oracle
non-network local connections being added to access control list

现在可以了
[oracle@localhost ~]$ cd /fantlam
[oracle@localhost fantlam]$ ls
database oracle
[oracle@localhost fantlam]$ cd database
[oracle@localhost database]$ ls
doc install README runInstaller stage welcome.html
[oracle@localhost database]$ ./runInstaller
正在启动 Oracle Universal Installer…

检查临时空间: 必须大于 80 MB。   实际为 7157 MB    通过
检查交换空间: 必须大于 150 MB。   实际为 1498 MB    通过
检查监视器: 监视器配置至少必须显示 256 种颜色。    实际为 16777216    通过
准备从以下地址启动 Oracle Universal Installer /tmp/OraInstall2009-08-03_01-05-30AM. 请稍候…

oracle已经读取了环境变量了 选择高级安装

这个错误可以不理,是目录权限问题,改了一下就好了,直接确定

把完整路径设置为/fantlam/oralnventory

安装企业版

继续下一步

正在重新检查安装程序要求….
准备从以下地址启动 Oracle Universal Installer /tmp/OraInstall2009-08-03_12-59-58AM. 请稍候…[oracle@localhost database]$ Xlib: connection to ":0.0" refused by server
Xlib: No protocol specified

Exception in thread "main" java.lang.InternalError: Can’t connect to X11 window server using ‘:0.0′ as the value of the DISPLAY variable.
        at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
        at sun.awt.X11GraphicsEnvironment.access$000(X11GraphicsEnvironment.java:53)
        at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:142)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:131)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:164)
        at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:68)
        at java.awt.Window.init(Window.java:270)
        at java.awt.Window.<init>(Window.java:318)
        at java.awt.Frame.<init>(Frame.java:419)
        at oracle.ewt.popup.PopupFrame.<init>(Unknown Source)
        at oracle.ewt.lwAWT.BufferedFrame.<init>(Unknown Source)
        at oracle.sysman.oio.oioc.OiocOneClickInstaller.<init>(OiocOneClickInstaller.java:328)
        at oracle.sysman.oio.oioc.OiocOneClickInstaller.<clinit>(OiocOneClickInstaller.java:168)

报错了,上网查了一下,找到了解决方法

在root下执行xhost local:oracle

CentOS5.3安装Oracle11g(图文)(三)

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://fantlam.blogbus.com/logs/43413431.html

接下来是配置环境了

设置用户

[root@localhost /]# groupadd oinstall   (创建用户组oinstall)

[root@localhost /]# groupadd dba(创建用户组dba)

[root@localhost /]# cd /

[root@localhost /]# mkdir –p /fantlam/oracle

(建立目录 mkdir命令:-p 确保目录名称存在,不存在的就建一个)

[root@localhost /]# useradd –g oinstall –G dba –d /fantlam/oracle oracle( 添加oracle用户到oinstall组dba副组 到/fantlam/oracle目录中 )

[root@localhost /]# passwd oracle(设置密码)

[root@localhost /]# chown -R oracle:oinstall fantlam(改目录组)

[root@localhost /]# ls -al(可以看到红色部分已经改了)

总计 172

drwxr-xr-x 24 root   root      4096 08-02 23:39 .

drwxr-xr-x 24 root   root      4096 08-02 23:39 ..

-rw-r–r–   1 root   root         0 08-02 22:44 .autofsck

drwxr-xr-x   2 root   root      4096 08-02 22:24 bin

drwxr-xr-x   3 root   root      4096 08-02 22:19 boot

drwxr-xr-x 11 root   root      4020 08-02 22:49 dev

drwxr-xr-x 98 root   root     12288 08-02 23:42 etc

drwxr-xr-x   3 oracle oinstall 4096 08-02 23:39 fantlam

drwxr-xr-x   2 root   root      4096 08-02 23:36 home

drwxr-xr-x 13 root   root      4096 08-02 22:24 lib

drwx——   2 root   root     16384 08-02 22:06 lost+found

drwxr-xr-x   2 root   root      4096 03-10 06:42 media

drwxr-xr-x   2 root   root         0 08-02 22:46 misc

drwxr-xr-x   2 root   root      4096 03-10 06:42 mnt

drwxr-xr-x   2 root   root         0 08-02 22:46 net

drwxr-xr-x   2 root   root      4096 03-10 06:42 opt

dr-xr-xr-x 137 root   root         0 08-02 22:43 proc

drwxr-x— 16 root   root      4096 08-02 23:00 root

drwxr-xr-x   2 root   root     12288 08-02 22:22 sbin

drwxr-xr-x   4 root   root         0 08-02 22:43 selinux

drwxr-xr-x   2 root   root      4096 03-10 06:42 srv

drwxr-xr-x 11 root   root         0 08-02 22:43 sys

drwxrwxrwt 10 root   root      4096 08-02 23:00 tmp

drwxr-xr-x 14 root   root      4096 08-02 22:17 usr

drwxr-xr-x 22 root   root      4096 08-02 22:26 var

[root@localhost /]# id nobody (确保用户存在)

uid=99(nobody) gid=99(nobody) groups=99(nobody) context=root:system_r:unconfined_t:SystemLow-SystemHigh

关于域名的配置,为了保证安装过程不会出现意外 需要做一些配置

一下几个命令是文档给出的

[root@localhost /]# cat /etc/nsswitch.conf | grep hosts

#hosts:     db files nisplus nis dns

hosts:      files dns

[root@localhost /]# hostname

localhost.localdomain

[root@localhost /]# domainname

(none)

[root@localhost /]# cat /etc/hosts

# Do not remove the following line, or various programs

# that require network functionality will fail.

127.0.0.1               localhost.localdomain localhost

::1             localhost6.localdomain6 localhost6

主要是这里 我修改一下文件 加上一行

[root@localhost /]# vi /etc/hosts

You have mail in /var/spool/mail/root

[root@localhost /]# cat /etc/hosts

# Do not remove the following line, or various programs

# that require network functionality will fail.

127.0.0.1               localhost.localdomain localhost

192.168.1.103           localhost.localdomain localhost

#::1             localhost6.localdomain6 localhost6

[root@localhost /]#

接下来配置三个重要文件 直接把它加到文件的最后

[root@localhost /]#vi /etc/sysctl.conf

kernel.shmall = 2097152

kernel.shmmax = 2147483648

kernel.shmmni = 4096

kernel.sem = 250 32000 100 128

net.ipv4.ip_local_port_range = 1024 65000

net.core.rmem_default = 262144

net.core.rmem_max = 4194304

net.core.wmem_default = 262144

net.core.wmem_max = 262144

[root@localhost /]#vi /etc/security/limits.conf

oracle              soft    nproc   2047

oracle              hard    nproc   16384

oracle              soft    nofile 1024

oracle              hard    nofile 65536

[root@localhost /]# vi /etc/profile

if [ $USER = "oracle" ]; then

        if [ $SHELL = "/bin/ksh" ]; then

ulimit -p 16384

              ulimit -n 65536

        else

              ulimit -u 16384 -n 65536

        fi

fi

切换到oracle用户,注意要用 su – root 命令(注意,‘-’的左右都有空格!)这样才确保把环境带过去

如果只是su root是不会把环境带过去的

[root@localhost /]# su – oracle

[oracle@localhost ~]$ ls -al

总计 48

drwx—— 3 oracle oinstall 4096 08-03 00:16 .

drwxr-xr-x 3 oracle oinstall 4096 08-03 00:16 ..

-rw-r–r– 1 oracle oinstall   33 08-03 00:16 .bash_logout

-rw-r–r– 1 oracle oinstall 176 08-03 00:16 .bash_profile

-rw-r–r– 1 oracle oinstall 124 08-03 00:16 .bashrc

drwxr-xr-x 4 oracle oinstall 4096 08-03 00:16 .mozilla

[oracle@localhost ~]$ vi .bash_profile(设置环境变量)

export PATH

ORACLE_BASE=/fantlam

ORACLE_HOME=$ORACLE_BASE/oracle

ORACLE_SID=fantlam

PATH=$ORACLE_HOME/bin:$PATH

export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH

关于.bash_profile和.bashrc的区别

/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.
并从/etc/profile.d目录的配置文件中搜集shell的设置.
/etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.
~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该
文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该
该文件被读取.
~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件.

另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系.

~/.bash_profile 是交互式、login 方式进入 bash 运行的
~/.bashrc 是交互式 non-login 方式进入 bash 运行的
通常二者设置大致相同,所以通常前者会调用后者。

[root@localhost ~]#exit (退出登录让设置生效)

[root@localhost ~]# su – oracle

[oracle@localhost ~]$ env | grep ORA

ORACLE_SID=fantlam

ORACLE_BASE=/fantlam

ORACLE_HOME=/fantlam/oracle

[oracle@localhost ~]$

CentOS5.3安装Oracle11g(图文)(二)

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://fantlam.blogbus.com/logs/43412706.html

接下来是检测所需要的包

参照官方文档

Asianux 3.0, Oracle Enterprise Linux 5.0, and Red Hat Enterprise Linux 5.0

The following packages (or later versions) must be installed:
binutils-2.17.50.0.6-2.el5
compat-libstdc++-33-3.2.3-61
elfutils-libelf-0.125-3.el5
elfutils-libelf-devel-0.125
gcc-4.1.1-52
gcc-c++-4.1.1-52
glibc-2.5-12
glibc-common-2.5-12
glibc-devel-2.5-12
glibc-headers-2.5-12
libaio-0.3.106
libaio-devel-0.3.106
libgcc-4.1.1-52
libstdc++-4.1.1
libstdc++-devel-4.1.1-52.e15
make-3.81-1.1
sysstat-7.0.0

所以我们要一个一个检测看有没缺 使用命令 rpm -qa | grep (rpm -q也可以)

我把找出来的标为蓝色

[root@localhost ~]# rpm -qa | grep binutils

binutils-2.17.50.0.6-9.el5

[root@localhost ~]# rpm -qa | grep compat

compat-gcc-34-3.4.6-4

compat-libstdc++-296-2.96-138

compat-gcc-34-c++-3.4.6-4

avahi-compat-libdns_sd-0.6.16-1.el5

compat-gcc-34-g77-3.4.6-4

compat-glibc-2.3.4-2.26

compat-glibc-headers-2.3.4-2.26

compat-libf2c-34-3.4.6-4

compat-libstdc++-33-3.2.3-61

java-1.4.2-gcj-compat-1.4.2.0-40jpp.115

[root@localhost ~]# rpm -qa | grep elfutils

elfutils-0.137-3.el5

elfutils-libelf-devel-0.137-3.el5

elfutils-libelf-devel-static-0.137-3.el5

elfutils-libelf-0.137-3.el5

elfutils-libs-0.137-3.el5

[root@localhost ~]# rpm -qa | grep gcc

compat-gcc-34-3.4.6-4

libgcc-4.1.2-44.el5

gcc-c++-4.1.2-44.el5

compat-gcc-34-c++-3.4.6-4

compat-gcc-34-g77-3.4.6-4

gcc-gfortran-4.1.2-44.el5

gcc-4.1.2-44.el5

[root@localhost ~]# rpm -qa | grep glibc

glibc-devel-2.5-34

glibc-2.5-34

glibc-headers-2.5-34

glibc-common-2.5-34

compat-glibc-2.3.4-2.26

compat-glibc-headers-2.3.4-2.26

[root@localhost ~]# rpm -qa | grep libaio

libaio-0.3.106-3.2

[root@localhost ~]# rpm -qa | grep libgcc

libgcc-4.1.2-44.el5

[root@localhost ~]# rpm -qa | grep libstdc

compat-libstdc++-296-2.96-138

libstdc++-4.1.2-44.el5

libstdc++-devel-4.1.2-44.el5

compat-libstdc++-33-3.2.3-61

[root@localhost ~]# rpm -qa | grep make

automake14-1.4p6-13

imake-1.0.2-3

automake-1.9.6-2.1

automake17-1.7.9-7

make-3.81-3.el5

automake16-1.6.3-8

automake15-1.5-16

[root@localhost ~]# rpm -qa | grep sysstat

[root@localhost ~]#

所以总共还缺了2个

binutils-2.17.50.0.6-2.el5

compat-libstdc++-33-3.2.3-61

elfutils-libelf-0.125-3.el5

elfutils-libelf-devel-0.125

gcc-4.1.1-52

gcc-c++-4.1.1-52

glibc-2.5-12

glibc-common-2.5-12

glibc-devel-2.5-12

glibc-headers-2.5-12

libaio-0.3.106

libaio-devel-0.3.106

libgcc-4.1.1-52

libstdc++-4.1.1

libstdc++-devel-4.1.1-52.e15

make-3.81-1.1

sysstat-7.0.0

我们使用FileZilla来传输文件 它支持SSH

记得以前和虚拟机VM之间传文件的时候,第一种就是建立个FTP,这样挺麻烦的,又要建个服务器,配个目录。第二种是利用VM的功能,装虚拟工具,然后可以直接拖文件,但这样也比较局限,只适用于VM。而用filezilla这种方式既不用配置又可以用在真实的主机上,所以这种方式才是最佳选择

把缺的2个rpm和oracle11g传上去 直接拖进去就可以了 我放在了/home里了

传完后,进入home 把rpm装上

[root@localhost ~]# cd /home

[root@localhost home]# ls

libaio-devel-0.3.106-3.2.i386.rpm sysstat-7.0.2-3.el5.i386.rpm

linux_11gR1_database_1013.zip

[root@localhost home]# rpm -ivh *.rpm

warning: libaio-devel-0.3.106-3.2.i386.rpm: Header V3 DSA signature: NOKEY, key ID e8562897

Preparing…                ########################################### [100%]

   1:libaio-devel           ########################################### [ 50%]

   2:sysstat                ########################################### [100%]

[root@localhost home]#

现在是一切准备就绪,可以正式开始了

CentOS5.3安装Oracle11g(图文)(一)

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://fantlam.blogbus.com/logs/43410551.html

在linux安装oracle,一直以来都想做的事,一直都没找到合适的机会

今天结合网上的教程和官方文档,来个安装图解

采用版本 centos5.3 和oracle 11g

centos我们知道是开源免费的,当然官方要求的版本没有包括它,但是它其实就等于redhat enterprise

官方:

On Linux x86 and Linux x86-64:

Asianux 2.0

Asianux 3.0

Oracle Enterprise Linux 4.0

Oracle Enterprise Linux 5.0

Red Hat Enterprise Linux 4.0

Red Hat Enterprise Linux 5.0

SUSE Linux Enterprise Server 10.0

centos5.3就等于redhat enterprice 5 update 3

现在开始。。。首先安装centos5.3 过程我就不多讲了 如果有人不知道怎么安装,可以参考我blog其它文章

安装有几个地方要注意的,一个就是分区

参照官方文档说明

At least 1 GB of RAM

To determine the RAM size, enter the following command:

# grep MemTotal /proc/meminfo

RAMSwap Space

Between 1024 MB and 2048 MB1.5 times the size of RAM

Between 2049 MB and 8192 MBEqual to the size of RAM

More than 8192 MB0.75 times the size of RAM

内存要求是1G以上 swap分区也有大小要求 所以自动的话可以swap分区就会不够,为了保险,还是手动分配一下分区空间 我给了1G多的swap 剩下的给系统分区 还有就是虚拟机空间给大点 默认的8G 第一次我安装就出现空间不足的问题 所以这次我给了16G 保证不会有硬盘不足

第二点就是需要把一些开发包给装上 比如GCC 所以在定制软件那里要把开发的库勾上,而像其它什么音频办公游戏那些东西可以不要掉

之后是装完系统的时候 必须保证它能联网

虚拟机设置网络方式为bridged 方式 采用DHCP 激活网络 则可以上网

输入ifconfig 得出自己的IP为192.168.1.103

这样一个linux主机就算配好了 接下来准备2个工具

远程登录 Putty

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

文件传输 FileZilla

http://filezilla-project.org/download.php?type=client

准备采用的方式是用远程操作,当然直接在linux上也是可以的,不过安装过程有些需要拷贝工作,在windows下用远程比较方便,而且一般真实情况也是通过远程去操作linux主机的,所以本次决定这么做。

准备官方文档

Oracle Database

Installation Guide

11g Release 1 (11.1) for Linux

B32002-06

参看官方文档b32002.pdf(可以到oracle官网选择下载)

Putty是开源小巧的软件 很方面使用 不用安装 因为它支持SSH 而且centos默认已经开了SSH 所以我们输入IP192.168.1.103 端口22登录

还有一点为了保证客户端不会出现中文乱码,我们需要设置一下编码为UTF-8 因为linux编码是UTF-8

登录进去 输入用户名密码 输入命令查看一下系统信息

包括检测内存大小 内核版本 TMP空间够不够的问题 大致上应该没什么问题了

在CentOS5.3上安装Oracle 10g总结文档

一.前言

    之前听坊间传闻说安装Oracle很BT,今日一试,果然如此:<,所以决心把安装中遇到的问题整理成此文档,以备后来者参考。

二.基本配置   

    在安装Oracle之前,我想先说一下机器配置的问题,因为单机器的问题,就可能会浪费你1天多的时间!

(1)硬盘剩余空间:10G以上

    虽然Oracle 10g的安装文件只有800多MB,但安装后的oracle+oraInventory目录会用差不多4G空间,再加上安装时Oracle生成的临时文件 (/tmp目录需要至少400MB)…所以10G的硬盘空间已经是最低配置了,因为你可能还需要应付一些特殊情况。

(2)内存1.5G以上

    官方文档说512M内存也可以安装。是的,确实如此,但安装后能不能正常运行,我就不敢保证了…之前我用一台1G内存的虚拟机安装Oracle 10g,正要启动的时候提示:剩余内存不足。为了避免不必要的麻烦,请把内存加多一些。

(3)Swap交换区2G

三.在CenOS5.3上安装Oracle 10g

1.预备资源

【1】《Oracel 10g官方安装文档

【2】 安装包:10201_database_linux_x86_64.cpio.gz

2.安装Oracle 10g

【1】准备安装

为了避免缺包导致的Error,请在安装Oracle之前执行以下命令:

yum install yum-fastestmirror -y
yum install compat-db*
yum install compat-libc*
yum install compat-gcc*
yum install libXp.so.6
yum install libc-*
yum install libaio*
yum install openmotif
yum install glibc-devel*
yum install libgcc*
yum install gnome-lib*

【2】安装包解压

zcat /tmp/10201_database_linux_x86_64.cpio.gz /data/setupfiles/Oracle/ | cpio -idmv

【3】创建 Oracle 组和用户帐户

创建用于安装和维护Oracle 10g 软件的账户。用户帐户将称为oracle,而组将称为oinstall和dba。以root用户身份执行以下命令:

# /usr/sbin/groupadd oinstall
# /usr/sbin/groupadd dba
# /usr/sbin/useradd -m -g oinstall -G dba oracle
# id oracle
uid=501(oracle) gid=501(oinstall) groups=501(oinstall),502(dba)

设置oracle帐户的口令

# passwd oracle
Changing password for user oracle.
New password:
Retype new password:
passwd:all authentication tokens updated successfully.

【4】创建目录

创建Oracle 10g及其数据库文件的目录,以root用户身份执行以下命令:

# mkdir -p /data1/oracle
# mkdir -p /data1/oradata
# chown -R oracle:oinstall /data1/oracle /data1/oradata
# chmod -R 775 /data1/oracle /data1/oradata

【5】修改内核参数

安装Oracle 10g需修改内核参数,否则安装检测时会报Failed,甚至导致安装时出现Error。以root身份执行以下命令:

cat >> /etc/sysctl.conf <<EOF
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default = 262144
net.core.rmem_max = 262144
net.core.wmem_default = 262144
net.core.wmem_max = 262144
EOF

如果检查没有问题后,即可以开始装Oralce 10g。

【6】安装Oracle 10g

(1)先以oracle用户身份登陆XWindow。因为oracle安装会弹出界面让你配置,如果使用putty登陆安装的话,你是没有办法操作弹出框的,所以一定要登录XWindow,然后在Terminal里启动安装程序。

    另外一个问题就是,必须要用oracle用户登陆XWindow,并以oracle用户在Terminal中启动安装程序。为什么不用root权限呢?首 先,以root用户登录XWindow并启动安装程序会出错,提示“The user is root. Oracle Universal Installer cannot continue installation if the user is root.”。如果以root登陆XWindow,以oracle用户在Terminal中启动安装程序,可能会出现某些对话框弹不出来,导致安装卡死的 情况,这种情况之前我就遇到过,虽然不能百分百确定是root登陆XWindow导致的问题,但为了避免不必要的问题,还是以oracle用户登录 XWindow,并用oracle身份启动安装程序。

(2)如果你的系统语言为中文,请把他设置为英文,否则安装的时候会出现乱码。

(3)Terminal中启动Oracle 10g安装程序:

[oracle@vmlincn80ce5 /]$ ./data/setupfiles/Oracle/database/runInstaller

如果一切正常,界面会弹出如下对话框:

如果在Terminal启动runInstaller时遇到“Checking operating system version: must be redhat-2.1, redhat-3, SuSE-9, SuSE-8 or UnitedLinux-1.0 Failed ”这种问题,表明oracle不能识别你的系统内核,这个问题可以通过修改内核配置文件解决,如下:

cat > /etc/redhat-release << EOF
Red Hat Enterprise Linux AS release 3 (Taroon)
EOF

(4)Oracle 10g安装配置

修改Oralce Home Localtion,填写database password后,按“Next”。如图:

(5)数据库配置

修改Inventory directory,Specify Operating System group name选:oinstall,然后“Next”,如图:


(6)Oracle安装前检查

检查一下有什么不符合安装要求,看是否需要修改配置,如果按照上面步骤下来,这里的warning应该为0,然后“Next”。

(7)Install Oracle 10g

直接按“Install”。

(8)Installing…

现在你可以去泡壶乌龙茶了……如果在虚拟机上安装,会花时间会更长些……Zzzzzzz

(9)Configuration Assistant

在软件安装完成之后,会自动进行Configuration Assistant的配置。

包括了Oracle Net Configuration Assistant,Oracle Database Configuration Assistant,iSQL*Plus Configuration Assistant的配置。

当Oracle Database Configuration Assistant配置完成时,会弹出一个确认框,里面记录了一些比较重要的信息,包括:SID,Server Parameter Filename以及Database Control URL等,如图:


这些信息以后比较有用,可以记录下来,然后“OK”。

(10)以root权限运行脚本

当iSQL*Plus Configuration Assistant配置完成时,会弹出一下框,里面有两个Srcipt需要你用root权限运行。


在Terminel中以root权限执行以上两个脚本:

[root@vmlincn80ce5 oradata]# ./orainstRoot.sh
Changing permissions of /data1/oradata to 770.
Changing groupname of /data1/oradata to oinstall.
The execution of the script is complete
[root@vmlincn80ce5 oracle]# ./root.sh
Running Oracle10 root.sh script...

The following environment variables are set as:
ORACLE_OWNER= oracle
ORACLE_HOME= /data1/oracle

Enter the full pathname of the local bin directory: [/usr/local/bin]:
Copying dbhome to /usr/local/bin ...
Copying oraenv to /usr/local/bin ...
Copying coraenv to /usr/local/bin ...


Creating /etc/oratab file...
Entries will be added to the /etc/oratab file as needed by
Database Configuration Assistant when a database is created
Finished running generic part of root.sh script.
Now product-specific root actions will be performed.

然后按“OK”。

(11)Oracle 10g安装完成

恭喜,Oracle 10g终于安装完成了:>,按“Exit”退出安装。


三.后记

    其实现在看来,安装Oracle 10g其实也并不是那么难搞,主要是在安装途中,可能会报出各种各样的Warnning/Error,这多数是系统缺少某些包导致的,如果把“【2.1】 准备安装”中的提到的包都装了,这类的问题应该基本上解决了(实在不行就Google吧…)。然后就是硬盘空间问题,每次Oracle安装都会在 /tmp下生成400MB左右的临时文件,如果安装中途出错退出的话,这些文件好像是不会自动删除的,所以记得把这些垃圾清掉,否则很容易导致硬盘空间不 足。

    关于Oracle的启动,找个时间再写一下。

CentOS 5安装图解

CentOS 5安装图解

CentOS5的安装形势与以往的CentOS有些变化,实际上的安装流程是没有太大的变化的,如果 你用过Fedora5以上的版本,就会发现他们非常的相像。

如果你不确认你的光盘是否完好,你可以选择OK来确认光盘是否完整。

这个地方要注意,因为要选择磁盘或分区,如果是一台机器多各系统,这个地方分区要多加小心。

这个地方按照自己的网络环境进行配置

按照自己的域名和网,以及DNS进行设置

从这里开始,除了开发项目中的开发工具,和基本系统中的基本选择外,其余的项目的选项都不选。

在基本系统的基本选项中的可选软件包中,去掉firstboot-tui。

linux下socket编程

什么是Socket
   Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。
   Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。

Socket建立
  为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。socket函数原型为:
   int socket(int domain, int type, int protocol);
   domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值"0"。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。
   Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。Socket执行体为你管理描述符表。
  两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。

Socket配置
  通过socket调用返回一个socket描述符后,在使用socket进行网络传输以前,必须配置该socket。面向连接的socket客户端通过调用Connect函数在socket数据结构中保存本地和远端信息。无连接socket的客户端和服务端以及面向连接socket的服务端通过调用bind函数来配置本地信息。
Bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。Bind函数原型为:
   int bind(int sockfd,struct sockaddr *my_addr, int addrlen);
   Sockfd是调用socket函数返回的socket描述符,my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;addrlen常被设置为sizeof(struct sockaddr)。
   struct sockaddr结构类型是用来保存socket信息的:
   struct sockaddr {
   unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14 字节的协议地址 */
};
   sa_family一般为AF_INET,代表Internet(TCP/IP)地址族;sa_data则包含该socket的IP地址和端口号。
   另外还有一种结构类型:
   struct sockaddr_in {
   short int sin_family; /* 地址族 */
   unsigned short int sin_port; /* 端口号 */
   struct in_addr sin_addr; /* IP地址 */
   unsigned char sin_zero[8]; /* 填充0 以保持与struct sockaddr同样大小 */
   };
  这个结构更方便使用。sin_zero用来将sockaddr_in结构填充到与struct sockaddr同样的长度,可以用bzero()或memset()函数将其置为零。指向sockaddr_in 的指针和指向sockaddr的指针可以相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向sockaddr_in的指针转换为指向sockaddr的指针;或者相反。
  使用bind函数时,可以用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号:
   my_addr.sin_port = 0; /* 系统随机选择一个未被使用的端口号 */
   my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本机IP地址 */
通过将my_addr.sin_port置为0,函数会自动为你选择一个未占用的端口来使用。同样,通过将my_addr.sin_addr.s_addr置为INADDR_ANY,系统会自动填入本机IP地址。
注意在使用bind函数是需要将sin_port和sin_addr转换成为网络字节优先顺序;而sin_addr则不需要转换。
  计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就需要进行转换,否则就会出现数据不一致。
   下面是几个字节顺序转换函数:
·htonl():把32位值从主机字节序转换成网络字节序
·htons():把16位值从主机字节序转换成网络字节序
·ntohl():把32位值从网络字节序转换成主机字节序
·ntohs():把16位值从网络字节序转换成主机字节序
   Bind()函数在成功被调用时返回0;出现错误时返回"-1"并将errno置为相应的错误号。需要注意的是,在调用bind函数时一般不要将端口号置为小于1024的值,因为1到1024是保留端口号,你可以选择大于1024中的任何一个没有被占用的端口号。

连接建立
  面向连接的客户程序使用Connect函数来配置socket并与远端服务器建立一个TCP连接,其函数原型为:
   int connect(int sockfd, struct sockaddr *serv_addr,int addrlen);
Sockfd是socket函数返回的socket描述符;serv_addr是包含远端主机IP地址和端口号的指针;addrlen是远端地质结构的长度。Connect函数在出现错误时返回-1,并且设置errno为相应的错误码。进行客户端程序设计无须调用bind(),因为这种情况下只需知道目的机器的IP地址,而客户通过哪个端口与服务器建立连接并不需要关心,socket执行体为你的程序自动选择一个未被占用的端口,并通知你的程序数据什么时候到打断口。
   Connect函数启动和远端主机的直接连接。只有面向连接的客户程序使用socket时才需要将此socket与远端主机相连。无连接协议从不建立直接连接。面向连接的服务器也从不启动一个连接,它只是被动的在协议端口监听客户的请求。
   Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。
   int listen(int sockfd, int backlog);
Sockfd是Socket系统调用返回的socket 描述符;backlog指定在请求队列中允许的最大请求数,进入的连接请求将在队列中等待accept()它们(参考下文)。Backlog对队列中等待服务的请求的数目进行了限制,大多数系统缺省值为20。如果一个服务请求到来时,输入队列已满,该socket将拒绝连接请求,客户将收到一个出错信息。
当出现错误时listen函数返回-1,并置相应的errno错误码。
   accept()函数让服务器接收客户的连接请求。在建立好输入队列后,服务器就调用accept函数,然后睡眠并等待客户的连接请求。
   int accept(int sockfd, void *addr, int *addrlen);
   sockfd是被监听的socket描述符,addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求);addrten通常为一个指向值为sizeof(struct sockaddr_in)的整型指针变量。出现错误时accept函数返回-1并置相应的errno值。
  首先,当accept函数监视的socket收到连接请求时,socket执行体将建立一个新的socket,执行体将这个新socket和请求连接进程的地址联系起来,收到服务请求的初始socket仍可以继续在以前的 socket上监听,同时可以在新的socket描述符上进行数据传输操作。

数据传输
   Send()和recv()这两个函数用于面向连接的socket上进行数据传输。
   Send()函数原型为:
   int send(int sockfd, const void *msg, int len, int flags);
Sockfd是你想用来传输数据的socket描述符;msg是一个指向要发送数据的指针;Len是以字节为单位的数据的长度;flags一般情况下置为0(关于该参数的用法可参照man手册)。
   Send()函数返回实际上发送出的字节数,可能会少于你希望发送的数据。在程序中应该将send()的返回值与欲发送的字节数进行比较。当send()返回值与len不匹配时,应该对这种情况进行处理。
char *msg = "Hello!";
int len, bytes_sent;
……
len = strlen(msg);
bytes_sent = send(sockfd, msg,len,0);
……
   recv()函数原型为:
   int recv(int sockfd,void *buf,int len,unsigned int flags);
   Sockfd是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度。Flags也被置为0。Recv()返回实际上接收的字节数,当出现错误时,返回-1并置相应的errno值。
Sendto()和recvfrom()用于在无连接的数据报socket方式下进行数据传输。由于本地socket并没有与远端机器建立连接,所以在发送数据时应指明目的地址。
sendto()函数原型为:
   int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
  该函数比send()函数多了两个参数,to表示目地机的IP地址和端口号信息,而tolen常常被赋值为sizeof (struct sockaddr)。Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
   Recvfrom()函数原型为:
   int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
   from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。fromlen常置为sizeof (struct sockaddr)。当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。Recvfrom()函数返回接收到的字节数或当出现错误时返回-1,并置相应的errno。
如果你对数据报socket调用了connect()函数时,你也可以利用send()和recv()进行数据传输,但该socket仍然是数据报socket,并且利用传输层的UDP服务。但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。

结束传输
  当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:
close(sockfd);
  你也可以调用shutdown()函数来关闭该socket。该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输继续进行。如你可以关闭某socket的写操作而允许继续在该socket上接受数据,直至读入所有数据。
   int shutdown(int sockfd,int how);
   Sockfd是需要关闭的socket的描述符。参数 how允许为shutdown操作选择以下几种方式:
   ·0——-不允许继续接收数据
   ·1——-不允许继续发送数据
   ·2——-不允许继续发送和接收数据,
   ·均为允许则调用close ()
   shutdown在操作成功时返回0,在出现错误时返回-1并置相应errno。

代码实例中的服务器通过socket连接向客户端发送字符串"Hello, you are connected!"。只要在服务器上运行该服务器软件,在客户端运行客户软件,客户端就会收到该字符串。

该服务器软件代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define SERVPORT 3333    /*服务器监听端口号 */
#define BACKLOG 10    /* 最大同时连接请求数 */

main()
{
    int sock_fd,client_fd;    /*sock_fd:监听socket;client_fd:数据传输socket */
    int sin_size;
    struct sockaddr_in my_addr;    /* 本机地址信息 */
    struct sockaddr_in remote_addr;    /* 客户端地址信息 */
    if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket创建出错!");
        exit(1);
    }
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(SERVPORT);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(my_addr.sin_zero),8);
    if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind出错!");
        exit(1);
    }
    if(listen(sock_fd, BACKLOG) == -1) {
        perror("listen出错!");
        exit(1);
    }
    while(1) {
        sin_size = sizeof(struct sockaddr_in);
        if((client_fd = accept(sock_fd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) {
            perror("accept出错");
            continue;
        }
        printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
        if(!fork()) {    /* 子进程代码段 */
            if(send(client_fd, "Hello, you are connected!\n", 26, 0) == -1) {
                perror("send出错!");
            }
            close(client_fd);
            exit(0);
        }
        close(client_fd);
    }
}

  服务器的工作流程是这样的:

  首先调用socket函数创建一个Socket,然后调用bind函数将其与本机地址以及一个本地端口号绑定,然后调用listen在相应的socket上监听,当accpet接收到一个连接服务请求时,将生成一个新的socket。服务器显示该客户机的IP地址,并通过新的socket向客户端发送字符串"Hello,you are connected!"。最后关闭该socket。

  代码实例中的fork()函数生成一个子进程来处理数据传输部分,fork()语句对于子进程返回的值为0。所以包含fork函数的if语句是子进程代码部分,它与if语句后面的父进程代码部分是并发执行的。

客户端程序代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100    /*每次最大数据传输量 */

main(int argc, char *argv[])
{
    int sock_fd, recvbytes;
    char buf[MAXDATASIZE];
    struct hostent *host;
    struct sockaddr_in serv_addr;
    if(argc< 2) {
        fprintf(stderr,"Please enter the server’s hostname!\n");
        exit(1);
    }
    if((host=gethostbyname(argv[1])) == NULL) {
        herror("gethostbyname出错!");
        exit(1);
    }
    if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket创建出错!");
        exit(1);
    }
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(SERVPORT);
    serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(serv_addr.sin_zero),8);
    if(connect(sock_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect出错!");
        exit(1);
    }
    if((recvbytes=recv(sock_fd, buf, MAXDATASIZE, 0)) == -1) {
        perror("recv出错!");
        exit(1);
    }
    buf[recvbytes] = ‘\0′;
    printf("Received: %s",buf);
    close(sock_fd);
}

  客户端程序首先通过服务器域名获得服务器的IP地址,然后创建一个socket,调用connect函数与服务器建立连接,连接成功之后接收从服务器发送过来的数据,最后关闭socket。

  函数gethostbyname()是完成域名转换的。由于IP地址难以记忆和读写,所以为了方便,人们常常用域名来表示主机,这就需要进行域名和IP地址的转换。函数原型为:

   struct hostent *gethostbyname(const char *name);

   函数返回为hosten的结构类型,它的定义如下:

   struct hostent {
     char *h_name;          /* 主机的官方域名 */
char **h_aliases;          /* 一个以NULL结尾的主机别名数组 */
int h_addrtype;         /* 返回的地址类型,在Internet环境下为AF-INET */
int h_length;           /* 地址的字节长度 */
char **h_addr_list;           /* 一个以0结尾的数组,包含该主机的所有地址*/
};
#define h_addr h_addr_list[0]       /*在h-addr-list中的第一个地址*/

   当 gethostname()调用成功时,返回指向struct hostent的指针,当调用失败时返回-1。当调用gethostbyname时,你不能使用perror()函数来输出错误信息,而应该使用herror()函数来输出。

  无连接的客户/服务器程序,在原理上和连接的客户/服务器是一样的,两者的区别在于无连接的客户/服务器中的客户一般不需要建立连接,而且在发送接收数据时,需要指定远端机的地址。

阻塞和非阻塞

  阻塞函数在完成其指定的任务以前不允许程序调用另一个函数。例如,程序执行一个读数据的函数调用时,在此函数完成读操作以前将不会执行下一程序语句。当服务器运行到accept语句时,而没有客户连接服务请求到来,服务器就会停止在accept语句上等待连接服务请求的到来。这种情况称为阻塞(blocking)。而非阻塞操作则可以立即完成。比如,如果你希望服务器仅仅注意检查是否有客户在等待连接,有就接受连接,否则就继续做其他事情,则可以通过将Socket设置为非阻塞方式来实现。非阻塞socket在没有客户在等待时就使accept调用立即返回。

   #include <unistd.h>
#include <fcntl.h>
……
sockfd = socket(AF_INET,SOCK_STREAM,0);
fcntl(sockfd,F_SETFL,O_NONBLOCK);
……

  通过设置Socket为非阻塞方式,可以实现"轮询"若干Socket。当企图从一个没有数据等待处理的非阻塞Socket读入数据时,函数将立即返回,返回值为-1,并置errno值为EWOULDBLOCK。但是这种"轮询"会使CPU处于忙等待方式,从而降低性能,浪费系统资源。而调用select()会有效地解决这个问题,它允许你把进程本身挂起来,而同时使系统内核监听所要求的一组文件描述符的任何活动,只要确认在任何被监控的文件描述符上出现活动,select()调用将返回指示该文件描述符已准备好的信息,从而实现了为进程选出随机的变化,而不必由进程本身对输入进行测试而浪费CPU开销。select函数原型为:

   int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

   其中readfds、writefds、exceptfds分别是被select()监视的读、写和异常处理的文件描述符集合。如果你希望确定是否可以从标准输入和某个socket描述符读取数据,你只需要将标准输入的文件描述符0和相应的sockdtfd加入到readfds集合中;numfds的值是需要检查的号码最高的文件描述符加1,这个例子中numfds的值应为sockfd+1;当select返回时,readfds将被修改,指示某个文件描述符已经准备被读取,你可以通过FD_ISSSET()来测试。为了实现fd_set中对应的文件描述符的设置、复位和测试,它提供了一组宏:

   FD_ZERO(fd_set *set)—-清除一个文件描述符集;
FD_SET(int fd,fd_set *set)—-将一个文件描述符加入文件描述符集中;
FD_CLR(int fd,fd_set *set)—-将一个文件描述符从文件描述符集中清除;
FD_ISSET(int fd,fd_set *set)—-试判断是否文件描述符被置位。

   Timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout长时间后没有文件描述符准备好即返回。struct timeval数据结构为:

  struct timeval {
int tv_sec; /* seconds */
int tv_usec; /* microseconds */
};

POP3客户端实例

  下面的代码实例基于POP3的客户协议,与邮件服务器连接并取回指定用户帐号的邮件。与邮件服务器交互的命令存储在字符串数组POPMessage中,程序通过一个do-while循环依次发送这些命令。

#include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define POP3SERVPORT 110
#define MAXDATASIZE 4096

main(int argc, char *argv[]){
int sock_fd;
struct hostent *host;
struct sockaddr_in serv_addr;
char *POPMessage[]={
"USER userid\r\n",
"PASS password\r\n",
"STAT\r\n",
"LIST\r\n",
"RETR 1\r\n",
"DELE 1\r\n",
"QUIT\r\n",
NULL
};
int iLength;
int iMsg=0;
int iEnd=0;
char buf[MAXDATASIZE];

if((host=gethostbyname("your.server"))==NULL) {
perror("gethostbyname error");
exit(1);
}
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket error");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(POP3SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if (connect(sock_fd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
perror("connect error");
exit(1);
}

do {
send(sock_fd,POPMessage[iMsg],strlen(POPMessage[iMsg]),0);
printf("have sent: %s",POPMessage[iMsg]);

iLength=recv(sock_fd,buf+iEnd,sizeof(buf)-iEnd,0);
iEnd+=iLength;
buf[iEnd]=’\0′;
printf("received: %s,%d\n",buf,iMsg);

iMsg++;
} while (POPMessage[iMsg]);

close(sockfd);
}

文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppsl/200861/118803.html)

Linux下C和C++开发基础

Linux下C和C++开发基础 作者 阿江 日期 2009-3-23 4:57:00

基本编程概念
n 编程语言:C 、C++
n 编译(compile):源文件(.c)->目标文件(.o)
n 连接(link):目标文件(.o)->可执行文件
n 库(library):静态连接库(.a)、动态连接库(.so)

Linux下开发工具
n编辑器:vi、emacs、窗口编辑器
n编译器:GCC
n调试器:GDB
n可执行文件工具:Binutils
n连接器:ld
n汇编程序:as
n库管理工具:ar
n可执行文件符号管理:nm
n显示可执行文件信息:objdump

简单程序示例(C语言):
n hello.c
/***************************

C代码 复制代码
  1. #i nclude <stdio.h>   
  2. int main(int argc,char **argv)   
  3. {   
  4. printf("HelloWorld!\n");   
  5. return 0;   
  6. }   
  7. /***************************   
  8. n编译方法:gcc –o hello hello.c   
  9. n运行方法:./hello   
  10. 简单程序示例(C++语言):  

n hello.cpp
/*******************************

C代码 复制代码
  1. #i nclude <iostream>   
  2. using namespace std;   
  3. int main(int argc,char **argv)   
  4. {   
  5. cout << "Hello World!“ << endl;   
  6. return 0;   
  7. }  

/*******************************
n 编译方法:g++ –o hello hello.cpp
n 运行方法:./hello
GCC编译器
n GNU平台下主流编译器
n目前最新稳定版4.0
n官方网站:http://gcc.gnu.org
n支持编译语言:C、C++、Objective-C、
Objective-C++、Java、Fortran、Ada
n跨平台支持:支持几乎所有主流操作系统,如
Linux、UNIX、Windows等。支持多种硬件平
台,如X86、ARM、PPC、MIPS等
n交叉编译功能

编译相关文件路径
n头文件
n一般在/usr/include目录下
n库文件
n一般在/lib、/usr/lib目录下
n某些库在其他目录下,如X Window相关库一般在
/usr/X11R6/lib目录下
n编译器、连接器核心文件
n一般在/usr/lib/gcc-lib/<target>/<version>目录下

Linux下函数库
n静态库(.a)和动态库(.so)
n库命名:lib开头,库版本号
n库链接
n标准库:
n动态加载库:ld-linux.so(/lib)
n标准C库:libc.so(/lib)
n标准C++库:libstdc++.so(/usr/lib)
n数学库:libm.so(/lib)

GCC使用用法
n基本用法:
n gcc [options] file…
n示例:gcc –o hello hello.c,编译hello.c为可执行文件
hello(自动连接标准C库libc.so)
n示例:gcc –o hello hello.c –lm,编译hello.c为可执行
文件hello,连接数学库libm
n示例:g++ -o hello hello.cpp,编译hello.cpp为可执行
文件hello,自动连接标准C++库libstdc++.so

GCC常用选项
-v :显示gcc版本信息及其相关信息
n示例:gcc -v
n可用于查看gcc核心文件信息及其编译配置选项
n -o:生成可执行文件名
n示例:gcc -o hello hello.c
n -c:仅编译成中间目标文件(.o),不连接
n示例:gcc -c hello.c,将生成hello.o
n -S:由源程序生成汇编文件(.s)
n示例:gcc -S hello.c,将生成hello.s
-E:对源程序仅进行预处理,输出到标准输出上(可
用于分析预处理如define的问题)
n 示例:gcc -E hello.c> hellop.c
n -I:指定头文件所在路径
n 示例:gcc -Iinclude -o hello hello.c
n -L:指定库文件所在路径
n 示例:gcc –o hello hello.c -Llib -ltest
n -l:指定连接的库文件
n 示例:同上
n -D:定义宏
n 示例:gcc -D DEBUG=3 -o hello hello.c
-On:代码优化选项,以产生更小和更快的目标代码,
n表示优化级别,如-O1,-O2,-O3等
n 示例:gcc -O2 -o hello hello.c
n -m<arch>:针对特定处理器的优化,如-m386,-m586等
n 示例:gcc -m586 -o hello hello.c
n -g:产生调试代码,用于gdb调试工具
n 示例:gcc -g -o hello hello.c
n -pg:产生用于性能测试的附加信息,供gprof程序使用
n 示例:gcc -pg -o hello hello.c
n -Wall:显示所有警告信息
n 示例:gcc -Wall -o hello hello.c

GNU调试工具gdb
n基本功能:
n设置断点,暂停程序执行
n监视运行状态下变量值
n单步执行代码
n汇编、反汇编
n调试信息
n源程序编译时加上-g选项,保证目标程序内含调试
信息,方便gdb调试时显示代码行、变量名等。

GDB调试示例程序test.c

C代码 复制代码
  1. #i nclude <stdio.h>   
  2. int main()   
  3. {   
  4. int i,j;   
  5. j=0;   
  6. for(i=0;i<10;i++)   
  7. {   
  8. j+=2;   
  9. printf(“j=%d\n”,j);   
  10. }   
  11. }  

GDB调试命令
n 编译:gcc -g -o test test.c
n 运行gdb:gdb test
n gdb命令:
n help:可查看gdb命令帮助
n gdb命令可采用缩写,如list可缩写为l
n 列出源文件:list
n 设置断点:break
n 示例:break 6,在第6行设置断点
n 示例:break <filename>:<linenum>,在特定源文件的特定行设置断点
n 示例:break <>,在函数上设置断点
n 示例:break *<address>,在特定地址上设置断点
n 运行:run,在断点处程序暂停

GDB调试命令
n 打印变量值:print,printf
n 示例:print i,打印变量i的值
n 示例:print i=10,将变量i赋值为10
n 示例:printf “0x%x\n”,j+20,按格式打印变量值
n 设置表达式观察点:awatch、watch
n 功能:awatch当变量被读写时暂停程序运行,watch当变量发生改变时暂停程序运行
n 示例:awatch j,当j发生改变时暂停运行,显示原值和新值;j被读时显示当前值
n 继续运行:continue
n查看当前断点:info break
n清除断点:clear
n示例:clear 6,清除第6行设置的断点
n删除断点:delete
n示例:delete 2,删除编号为2的断点
n屏蔽断点:disable
n示例:disable 2,暂时使编号为2的断点失效
n激活断点:enable
n示例:enable 2,重新激活编号为2的断点
n条件断点:
n示例:break 8 if j==8,每执行到第8行检测j的值,如果j=8则程序暂停
n其他断点命令:
n ignore:忽略断点特定次数
n tbreak:设置临时断点,仅执行一次
n单步运行:step,跟踪到函数内部
n单步运行:next,不跟踪到函数内部
n显示表达式值:display,每运行到断点均显示值
n显示display的表达式:info display
n删除display的表达式:delete display <编号>
n设置变量值:set variable
n示例:set variable i=8
n打印当前堆栈信息:backtrace
n设置运行时参数:set args
n源程序编译时-l选项可自动连接相应动态库
n查看目标文件使用的动态库ldd
n示例:ldd hello
n动态库路径
n默认/lib,/usr/lib
n由/etc/ld.so.conf指定
n ldconfig程序根据/etc/ld.so.conf重建动态库cache
n ld-linux.so动态库负责完成动态链接
n环境变量LD_LIBRARY_PATH

n全称:executable and linkable format
n目标文件:可重定位文件(relocatable,.o),可执行文件,静态库,动态库等
n ELF文件组成
n文件头ELF header
n程序段,典型的段.text(代码段)、.bss(未初始化的数据段)、.data(初始化的数据段)
n重定位和位置无关代码(PIC)

二进制文件工具binutils
n 用于查看和操作二进制文件
n 包含工具:
n 连接器:ld
n 汇编器:as
n 转换地址到源程序行:addr2line
n 建立、修改函数库:ar
n 列出目标文件的符号表:nm
n 目标文件转换和拷贝:objcopy
n 显示目标文件信息:objdump
n 删除目标文件中的符号表:strip
n 显示elf文件信息:readelf

二进制文件工具使用示例
n查看目标文件基本信息
n示例:readelf –h hello
n查看目标文件中的符号
n示例:nm hello
n查看目标文件中的段信息
n示例:objdump –h hello
n反汇编目标文件
n示例:objdump –d hello
n删除目标文件中的符号,减小文件大小
n示例:strip hello
n显示可执行文件中的常量串
n示例:strings hello

编程帮助
n man:用于查看标准命令、系统调用和函数库等的用法
n示例:man sleep(查看标准命令sleep)
n示例:man 3 sleep(查看函数sleep的用法)
n Info:查看命令用法,类似Web页面
n示例:info gcc,查看gcc用法
n示例:info libc,查看标准C函数

Source Insight使用教程–方便阅读linux内核源码

作为一个开放源代码的操作系统,Linux附带的源代码库使得广大爱好者有了一个广泛学习、深入钻研的机会,特别是Linux内核的组织极为复杂,同时,又不能像windows平台的程序一样,可以使用集成开发环境通过察看变量和函数,甚至设置断点、单步运行、调试等手段来弄清楚整个程序的组织结构,使得Linux内核源代码的阅读变得尤为困难。

当然Linux下的vimemacs编辑程序并不是没有提供变量、函数搜索,彩色显示程序语句等功能。它们的功能是非常强大的。比如,vimemacs就各自内嵌了一个标记程序,分别叫做ctagetag,通过配置这两个程序,也可以实现功能强大的函数变量搜索功能,但是由于其配置复杂,linux附带的有关资料也不是很详细,而且,即使建立好标记库,要实现代码彩色显示功能,仍然需要进一步的配置(在另一片文章,我将会讲述如何配置这些功能),同时,对于大多数爱好者来说,可能还不能熟练使用vimemacs那些功能比较强大的命令和快捷键。

为了方便的学习Linux源程序,我们不妨回到我们熟悉的window环境下,也算是“师以长夷以制夷”吧。但是在Window平台上,使用一些常见的集成开发环境,效果也不是很理想,比如难以将所有的文件加进去,查找速度缓慢,对于非Windows平台的函数不能彩色显示。于是笔者通过在互联网上搜索,终于找到了一个强大的源代码编辑器,它的卓越性能使得学习Linux内核源代码的难度大大降低,这便是Source Insight3.0,它是一个Windows平台下的共享软件,可以从 http://www.sourceinsight.com/上边下载30天试用版本。由于Source Insight是一个Windows平台的应用软件,所以首先要通过相应手段把Linux系统上的程序源代码弄到Windows平台下,这一点可以通过在linux平台上将/usr/src目录下的文件拷贝到Windows平台的分区上,或者从网上光盘直接拷贝文件到Windows平台的分区来实现。

下面主要讲解如何使用Source Insight,考虑到阅读源程序的爱好者都有相当的软件使用水平,本文对于一些琐碎、人所共知的细节略过不提,仅介绍一些主要内容,以便大家能够很快熟练使用本软件,减少摸索的过程。

安装Source Insight并启动程序,可以进入图1界面。在工具条上有几个值得注意的地方,如图所示,图中内凹左边的是工程按钮,用于显示工程窗口的情况;右边的那个按钮按下去将会显示一个窗口,里边提供光标所在的函数体内对其他函数的调用图,通过点击该窗体里那些函数就可以进入该函数所在的地方。



由于Source Insight实质上是一个支持多种开发语言(java,c ,c++等等)的编辑器,只不过由于其查找、定位、彩色显示等功能的强大,而被我们当成源代码阅读工具使用。所以,为了有效的阅读源程序,首先必须选择功能菜单上的 “Project”选项的子菜单“New Project”新建一个项目,项目名称可以自由选定,当然也可以选择删除(Remove)一个项目。当删除一个项目的时候,并不删除原有的源代码文件,只是将该软件生成的那些工程辅助文件删除。设定之后,将会弹出一个对话框如图2,接受默认选择,如果,硬盘空间足够,可以将第一个复选框选上,该选项将会需要与源代码大致同等的空间来建立一个本地数据库以加快查找的速度。

由于Source Insight实质上是一个支持多种开发语言(java,c ,c++等等)的编辑器,只不过由于其查找、定位、彩色显示等功能的强大,而被我们当成源代码阅读工具使用。所以,为了有效的阅读源程序,首先必须选择功能菜单上的 “Project”选项的子菜单“New Project”新建一个项目,项目名称可以自由选定,当然也可以选择删除(Remove)一个项目。当删除一个项目的时候,并不删除原有的源代码文件,只是将该软件生成的那些工程辅助文件删除。设定之后,将会弹出一个对话框如图2,接受默认选择,如果,硬盘空间足够,可以将第一个复选框选上,该选项将会需要与源代码大致同等的空间来建立一个本地数据库以加快查找的速度。



2 工程设置

点击“OK”按钮 邮苎≡窈螅 嵊幸桓鲂碌亩曰翱虻 觯 谡飧龆曰翱蚶铮 梢匝≡窠 亩恋奈募 尤牍こ蹋 恢址绞绞峭ü 贔ile Name中输入要阅读源代码文件的名称,点击“Add”按钮将其加入,也可以通过其中“Add All”和“Add Tree”两个按钮可以将选中目录的所有文件加入到工程中,其中“Add All”选项会提示加入顶层文件和递归加入所有文件两种方式,而“Add Tree”相当于“Add All”选项的递归加入所有文件,可以根据需要使用,就我来说,更喜欢“Add Tree”一些。由于该程序采用了部分打开文件的方式,没有用到的文件不会打开,所以,加入数千个文件也不用担心加入的文件超出程序的所能容忍的最大值,我就是采用“Add Tree”的方式将Linux2.4内核的四千五百九十一个文件加入的。



3 添加文件

加入文件后,点击一个文件,可以出现使用界面,如图4所示,其中,右边的那个窗口(Linux Project,即工程窗口)缺省按照字母顺序列出当前工程中所有的文件。



4 工作窗口

点击一个文件就可以打开该文件,显示如图5所示,进入到右边的那个窗口分别可以以文件列表的方式,列出所有的文件,每个窗体下边有一排按钮,左边的窗口(21142.c)从左至右分别为:按字母顺序排列所有标记、按照文件中行数顺序排列标记、按照类型排列标记、浏览本地文件标记、标记窗口属性。右边的窗口(Linux Project)从左至右分别为:按字母顺序文件列表、显示文件夹、按照文件类型归类文件、全部文件的所有标记列表、按照标记类型归类标记、跳转到定义处、显示标记信息、浏览工程标记、查找函数调用、工程属性,其中全部文件的所有标记列表选项可能要一段时间抽取标记,同步到数据库去,如果开始选择了建立标记数据库,将会在今后节省同步时间,最有用的莫过于浏览标记信息和查找函数调用,前者可以通过“Jump”按钮在不同的地方查找同样的标志,还可以通过“Reference”按钮结合后者进行全局的标记查找。

Reference功能是Source Insight的特色之一,它可以在速度极快的在整个工程中找到所有的标记,并且在该行程序的前边加上红色箭头的小按钮链接上。图6是一个Reference搜索后的结果,它可以有两种模式,一种集中显示结果,图6显示的就是这种模式,在这种模式下,可以通过前边的红色箭头小按钮进入另外一种模式,该标记的具体的所在处,也可以通过标记的具体所在处点击红色箭头小按钮进入警种模式,还可以通过工具条上的两个红色小箭头直接在第二种模式下前后移动,察看相应信息。它的这个强大的功能使得阅读Linux源程序有如神助。但是要注意的是,当进行了第二次“Reference”时,它会提示你将结果集附加在第一个结果集的后边还是取代第一个结果集。如果选择前者,不能对结果集根据前后两次搜索结果进行分类,然后在其子类里进行移动,只能在整个结果集里移动;如果,选择后者,结果集将会被替换为第二次搜索的结果,略微有些不方便。



6 Reference的搜索结果

当然,Source Insight 还提供了一些其他常见的便利。比如:右键菜单几乎包含了程序的所有功能,可以在编辑窗口为程序加上行号,还可以统计整个工程的程序行数,当然还有功能强大却用不上自动完成功能,似乎连它的30天试用期也是别有用心――可以迫使你尽可能快速的阅读源程序,其他一些技巧大家可以在使用过程中慢慢摸索。怎么样?爱好读源代码的朋友,不妨马上去下载一个,去开始我们的Linux内核探险之旅吧